home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / COMMUNIC / 1572A.ZIP / KMT_IBM3.ZIP / MSGIBM.ASM next >
Assembly Source File  |  1989-07-10  |  120KB  |  2,430 lines

  1.         Name msgibm
  2. ; File MSGIBM.ASM
  3. ; Tektronix emulator for use with MS Kermit/IBM.
  4. ; Edit history:
  5. ; Last edit 21 Nov 1988
  6. ; 21 Nov 1988 Version 2.32
  7. ; 16 Sept 1988 Also look in 0fc00:50h for AT&T logo.
  8. ; 1 July 1988 Version 2.31
  9. ; 22 May 1988 Add support for ESC [ Pn ; Pn m (ANSI) screen coloring.
  10. ; 22 March 1988 Add global byte Tekgraf which forces graphics board type
  11. ;   0=auto-sensing, 1=cga, 2=ega, 3=VGA, 4=Hercules, 5=ATT. Tekgraf stored
  12. ;   here and set in file MSX by Set Term Graphics <board type>. Permit chars
  13. ;   to overlap existing pixels. [jrd]
  14. ; 27 Feb 1988 Add tests for Toshiba T3100 (tnx for assist from Rob Preuss),
  15. ;   for Olivetti M28/AT&T 6300+, and for DEC VAXmate II (tnx to Frank da Cruz)
  16. ;   Add pointer based dispatch to character-font drawing routine. Add tests
  17. ;   for stdin being a file rather than a device (keyboard). [jrd]
  18. ; 27 Jan 1988 Supress GIN and Status echos with Bypass byte. Bypass is reset
  19. ;  by receipt of BEL, LF, CR, US, escape sequences, terminal reset.
  20. ;  Bypass is set by receipt of ESC Control-E, ESC Control-X, ESC Control-Z.
  21. ;  Make GIN mode crosshairs remember last GIN mode postion until the terminal
  22. ;  is reset; make major steps smaller. Add ESC query-mark stands for DEL.
  23. ;  Make Horizontal Tab (Control-I) a non-printing cursor control character
  24. ;  to move right one column (with line wrap). Let real Hercules boards use
  25. ;  both pages of memory (clones behave differently), tnx to Daniel Gruner.
  26. ; 1 Jan 1988 version 2.30
  27. ; 31 Dec 1987 change name from msvibm to msgibm for final release. [jrd]
  28. ; 29 Dec 1987 Add ESC [ ? 3 8 l  as exit Tek mode command, from VT340's.[jrd]
  29. ; 26 Dec 1987 Add test to absorb echo of crosshairs report. [jrd]
  30. ; 22 Dec 1987 Revise parsing rules to make an escape sequence be a temporary
  31. ;  interruption to the current command (except Clear Screen seq). [jrd]
  32. ; Add Control-C and Control-Break as non-reporting exits from GIN mode. [jrd]
  33. ; 21 Dec 1987 Add AT&T 6300, Olivetti M24 presence tests and run code. [jrd]
  34. ; 16 Dec 1987 Correct screen coloring for 64KB mono/med res color egas. [jrd]
  35. ; 4 Dec 1987 Add quirks for Environments, such as TopView, Windows. [jrd]
  36. ; 3 Dec 1987 Let 128KB EGA boards save screens. [jrd]
  37. ; 30 Nov 1987 Add relative plotting, thanks to help from Bob Parks. [jrd]
  38. ; 24 Nov 1987 Add dashed line patterns. [jrd]
  39. ; 21 Nov 1987 Add full color background. [jrd]
  40. ; 15 Nov 1987 Do screen clears manually because a Bios mode-set keeps
  41. ;  interrupts off long enough to miss serial port characters. Make crosshairs
  42. ;  smaller. [jrd]
  43. ; 8 Nov 1987 Modularize line drawing using Bresneham's algorithm, use pointers
  44. ;  to action routines for different board types. Add screen save/restore.
  45. ;  Do display board presence tests. Add FS as point plot introducer. Allow
  46. ;  for virtual screens when operating under Environments (Windows, etc). [jrd]
  47. ; 1 Nov 1987 Heavy rewrite to integrate code into regular MS Kermit/IBM
  48. ;  material. [jrd]
  49. ;==============================================================================
  50. ; Original version for TI Pro computers by
  51. ; 12-Dec-84  Joe Smith, CSM Computing Center, Golden CO 80401
  52. ; adapted to IBM PC June 1987 by        Brian Holley,
  53. ;                                       Faculty of Economics and Politics
  54. ;                                       University of Cambridge, England
  55. ;                                       Email: BJH6@UK.AC.CAM.PHX
  56. ; Upgraded and integrated into MS Kermit 2.30 by Joe Doupnik, Utah State Univ.
  57. ;
  58. ;                  Description of Tektronix commands
  59. ;
  60. ; ESCAPE-CONTROL-E (ENQ) requests a status report
  61. ; ESCAPE-FORMFEED erases the screen.
  62. ; ESCAPE-CONTROL-X turns on bypass mode (no screen characters).
  63. ; ESCAPE-CONTROL-Z turns on the crosshairs (not on 4006 or 4025)
  64. ; ESCAPE-? is replaced by DEL code, to assist line plots with 7 bit systems.
  65. ; ESCAPE [ Pn ; Pn m  set screen colors. Pn = 30 + sum of colors for foregnd,
  66. ;  40 + sum of colors for background, Pn = 0 sets b/w, Pn = 1 for high
  67. ;  intensity. Colors are red = 1, green = 2, blue = 4.
  68. ; ESCAPE [ ? 3 8 l  exits Tek mode and returns to host text terminal type
  69. ;  (VT102 if none defined yet). This is an extension from DEC VT340's.
  70. ; CONTROL-] (GS) turns on plot mode, the first move will be with beam off.
  71. ; CONTROL-^ (RS) turns on incremental plot mode. RS space means move pen up
  72. ;  RS P means move pen down, following letters:A, E, D, F, B, J, H, I mean
  73. ;  move right, right and up, up, left and up, left, left and down, down, and
  74. ;  right and down, respectively. Ex: RS <space> J J J  means move three Tek
  75. ;  positions left and down with the pen up (invisibly).
  76. ; CONTROL-UNDERLINE (US) turns off plot mode, as does CR (for all but 4025).
  77. ; CONTROL-X switches from TEKTRONIX sub mode to NORMAL alpha mode but is
  78. ;  ignored if we are emulating a full Tek terminal rather than a sub mode
  79. ;  of DEC or Heath.
  80. ; FF erases screen.
  81. ; ESCAPE letter, where letter is accent grave (`), a-e sets the line drawing
  82. ;   pattern until reset to solid lines (same as escape accent) by command or
  83. ;   a terminal reset.
  84. ; where
  85. ;       ENQ = Control E
  86. ;       ESC = Control [ (left square bracket)
  87. ;       FF = Control L
  88. ;       FS = Control \ (backslash)
  89. ;       GS = Control ] (right square bracket)
  90. ;       RS = Control ^ (caret)
  91. ;       US = Control _ (underscore)
  92. ;
  93. ; The plot commands are characters which specify the absolute position to move
  94. ; the beam.  All moves except the one immediately after the GS character
  95. ; (Control-]) are with a visible trace.
  96. ;
  97. ; For 4010-like devices - The positions are from 0 to 1023 for both X and Y,
  98. ; although only 0 to 780 are visible for Y due to screen geometry.  The screen
  99. ; is 10.23 by 7.80 inches, and coordinates are sent as 1 to 4 characters.
  100. ;
  101. ; For 4014-like devices - The positions are from 0 to 4096, but each movement
  102. ; is a multiple of 4 positions unless the high-resolution LSBXY are sent.  This
  103. ; makes it compatible with the 4010 in that a full sized plot fills the screen.
  104. ;
  105. ; HIX,HIY = High-order 5 bits of position
  106. ; LOX,LOY = Middle-order 5 bits of position
  107. ; LSBXY   = Low-order 2 bits of X + low-order 2 bits of Y (4014 mode)
  108. ;
  109. ; Hi Y    Lo Y    Hi X    LSBXY   Characters sent (Lo-X always sent)
  110. ; ----    ----    ----    -----   ----------------------------------
  111. ; Same    Same    Same    Same                           Lo-X
  112. ; Same    Same    Same    Diff          LSB, Lo-Y,       Lo-X   4014
  113. ; Same    Same    Diff    Same               Lo-Y, Hi-X, Lo-X
  114. ; Same    Same    Diff    Diff          LSB, Lo-Y, Hi-X, Lo-X   4014
  115. ; Same    Diff    Same    Same               Lo-Y,       Lo-X
  116. ; Same    Diff    Same    Diff          LSB, Lo-Y,       Lo-X   4014
  117. ; Same    Diff    Diff    Same               Lo-Y, Hi-X, Lo-X
  118. ; Same    Diff    Diff    Diff          LSB, Lo-Y, Hi-X, Lo-X   4014
  119. ; Diff    Same    Same    Same    Hi-Y,                  Lo-X
  120. ; Diff    Same    Same    Diff    Hi-Y, LSB, Lo-Y,       Lo-X   4014
  121. ; Diff    Same    Diff    Same    Hi-Y,      Lo-Y, Hi-X, Lo-X
  122. ; Diff    Same    Diff    Diff    Hi-Y, LSB, Lo-Y, Hi-X, Lo-X   4014
  123. ; Diff    Diff    Same    Same    Hi-Y,      Lo-Y,       Lo-X
  124. ; Diff    Diff    Same    Diff    Hi-Y, LSB, Lo-Y,       Lo-X   4014
  125. ; Diff    Diff    Diff    Same    Hi-y,      Lo-Y, Hi-X, Lo-X
  126. ; Diff    Diff    Diff    Diff    Hi-y, LSB, Lo-Y, Hi-X, Lo-X   4014
  127. ; Offset for byte:                20h   60h  60h   20h   40h
  128. ;
  129. ; Note that LO-Y must be sent if HI-X has changed so that the TEKTRONIX knows
  130. ; the HI-X byte (in the range of 20h-3fh) is HI-X and not HI-Y.  LO-Y must
  131. ; also be sent if LSBXY has changed, so that the 4010 will ignore LSBXY and
  132. ; accept LO-Y.  The LSBXY byte is 60h + MARGIN*10h + LSBY*4 + LSBX. (MARGIN=0)
  133. ;
  134. ;
  135. ;
  136. ; External variable tekflg and calls to tekini, tekemu, tekesc, tekcls:
  137. ; Byte TEKFLG is non-zero when the Tek emulator is active; it is set by the
  138. ; startup code in tekini and is maintained in this file. Internal variable
  139. ; inited remembers if we have a graphics screen saved, etc.
  140. ; TEKINI must be called when entering the emulator to establish the graphics
  141. ; screen mode and to calculate the screen dimensions.
  142. ; TEKRINT reinitialize complete emulator.
  143. ; TEKESC is called from say mszibm.asm to invoke Tek emulation when the
  144. ; external procedures have detected an Escape Control-L sequence. An implicit
  145. ; initialization is done if necessary.
  146. ; TEKEMU is the normal entry point to pass a received character to the emulator.
  147. ; It too will do an implicit initialization, if required.
  148. ; TEKCLS clears the graphics screen, but only if the emulator is active.
  149. ; The emulator remains active during Connect mode Help, Status, and other
  150. ; interrupts which do not change the terminal type.
  151.  
  152.  
  153.         public  tekemu,tekini,tekrint,tekend,tekgraf    ; Terminal emulation
  154.         public  tekcls, tekesc, tekflg                  ;  used by msz file
  155.  
  156.         include mssdef.h
  157.  
  158. ENQ     equ     05h                     ; ^E ENQ for TEK enquiries
  159. CAN     equ     18h                     ; ^X to return to ANSI mode
  160. ESCZ    equ     1Ah                     ; SUB, ESC-^Z triggers crosshairs
  161. VT      equ     0bh                     ; ^K go up one line
  162. FS      equ     1ch                     ; ^\ for point plot mode
  163. GS      equ     1Dh                     ; ^] draw line (1st move is invisible)
  164. RS      equ     1Eh                     ; ^^ for incremental line plot mode
  165. US      equ     1Fh                     ; ^_ (underscore) returns to text mode
  166. accent  equ     60h                     ; accent grave
  167.  
  168. txtmode equ     4                       ; text mode for TEKTRONIX status
  169. maxtekx equ     1024                    ; horizontal and
  170. maxteky equ     780                     ; vertical resolution of TEK 4010
  171.  
  172. screen  equ     10h                     ; IBM Bios screen call
  173.  
  174. uparr   equ     72                      ; DOS scan codes for arrow keys
  175. dnarr   equ     80
  176. lftarr  equ     75
  177. rgtarr  equ     77
  178. homscn  equ     71                      ; DOS home screen scan code
  179. shuparr equ     '8'                     ; ascii codes for shifted arrows
  180. shdnarr equ     '2'
  181. shlftarr equ    '4'
  182. shrgtarr equ    '6'
  183.  
  184.                                         ; Graph_mode for different systems:
  185. cga     equ     6                       ; highest resolution mode for CGA
  186. mono    equ     7                       ; real monochrome display adapter
  187. colorega equ    14                      ; Low-res mode, color EGA
  188. monoega equ     15                      ; mono ega needs mode 15
  189. ega     equ     16                      ; Hi-res mode - EGA
  190. olivetti equ    72                      ; Olivetti's Hi-res - 50 lines text
  191. toshiba equ     74h                     ; Toshiba T3100, like Olivetti
  192. vaxmate equ     0D0h                    ; DEC VAXmate II, like Olivetti
  193. hercules equ    255                     ; pseudo mode for Hercules graphics
  194. ; Note: IBM VGA modes 17 & 18, 640 by 480, can be used by setting "ega" above
  195. ; to 17 or 18 and modifying ybot to be 479 and ymult to be 48 at label tekin5.
  196. ; The code will scale everything appropriately for the new screen size, but
  197. ; there will be insufficient memory to retain the entire graphics image.
  198. ; Manual override SET TERMINAL GRAPHICS VGA accomplishes these two steps.
  199.  
  200. segega  equ     0a000h                  ; segments of display memory, EGA,VGA
  201. segcga  equ     0b800h                  ; CGA, AT&T/Olivetti and relatives
  202. seghga  equ     0b000h                  ; HGA
  203. segmono equ     0b000h                  ; Monochrome
  204.  
  205.                                         ; Hercules equates:
  206. index   equ     03b4h                   ; 6845 index register
  207. cntrl   equ     03b8h                   ; Display mode control port
  208. hstatus equ     03bah                   ; status port
  209. scrn_on equ     8                       ; bit to turn screen on
  210. grph    equ     2                       ; graphics mode
  211. text    equ     20h                     ; text mode
  212. config  equ     03bfh                   ; configuration port
  213. genable equ     1+2                     ; enable graphics (1) on two pages (2)
  214.  
  215. hiy     equ     1                       ; codes for Tek graphics components
  216. loy     equ     2
  217. hix     equ     4
  218. lox     equ     3
  219.  
  220. datas   segment public 'datas'
  221.         extrn   flags:byte, portval:word, rxtable:byte, vtemu:byte
  222.         extrn   tv_mode:byte
  223.  
  224. xmult   dw      ?                       ; scaling factor for x is
  225. xdiv    dw      ?                       ;     xmult/xdiv
  226. ymult   dw      ?                       ; scaling factor for y is
  227. ydiv    dw      ?                       ;     ymult/ydiv
  228. xmax    dw      ?                       ;
  229. ybot    dw      ?                       ;
  230.  
  231. ; required for Hercules screen handling
  232.  
  233. gtable  db      35h,2dh,2eh,7           ; bytes for 6845 controller
  234.         db      5bh,2,57h,57h           ; - graphics mode
  235.         db      2,3,0,0
  236.  
  237. ttable  db      61h,50h,52h,0fh         ; bytes for 6845 controller
  238.         db      19h,6,19h,19h           ; - text mode
  239.         db      2,0dh,0bh,0ch
  240.  
  241. attlogo db      'OLIVETTI'              ; Olivetti M24/28, AT&T 6300 rom id
  242. attlen  equ     $-attlogo               ; length
  243. toshlogo db     '  TT33110000  TTOOSSHHIIBBAA' ; Toshiba T3100 logo
  244. toshlen equ     $-toshlogo              ; length
  245. declogo db      'Copyright Digital Equipment Corp' ; DEC VAXmate
  246. declen  equ     $-declogo
  247. ttstate dw      tektxt                  ; state machine control pointer
  248. prestate dw     0                       ; previous state, across interruptions
  249. visible db      0                       ; 0 to move, 1 to draw a line
  250. tek_hiy dw      0                       ; Y coordinate in Tektronix mode
  251. tek_loy db      0
  252. tek_hix dw      0                       ; X coordinate in Tektronix mode
  253. tek_lox db      0
  254. tek_lsb db      0                       ; Low-order 2 bits of X + low Y
  255.                                         ;       (4014 mode)
  256. status  db      0
  257. lastc   db      0                       ; last x/y coord fragment seen
  258. masktab db      80h,40h,20h,10h,8,4,2,1 ; quicker than calculations!
  259.                                         ; dashed line patterns
  260. linetab dw      0ffffh                  ; ESC accent    11111111 11111111
  261.         dw      0aaaah                  ; ESC a         10101010 10101010
  262.         dw      0f0f0h                  ; ESC b         11110000 11110000
  263.         dw      0fafah                  ; ESC c         11111010 11111010
  264.         dw      0ffcch                  ; ESC d         11111111 11001100
  265.         dw      0fc92h                  ; ESC e         11111100 10010010
  266.  
  267. linepat dw      0ffffh                  ; active line pattern, from above
  268.  
  269. ;End of init data
  270. IDSEQ   dw      tekem                   ; address of response to terminal
  271. CTLTAB  dw      0                       ; .. inquiry
  272. tekem   db      'IBM_TEK'               ; .. and the response
  273.         db      escape,'/Z',0
  274. x_coord dw      0                       ; Tek text char X coordinate
  275. y_coord dw      8                       ; Tek text char Y coordinate
  276. xcross  dw      0                       ; cross hairs to start at centre
  277. ycross  dw      0
  278. oldx    dw      0                       ; Tek coordinates of last point
  279. oldy    dw      767                     ;  initially top left
  280. scalex  dw      0                       ; PC coord for scaled x value
  281. scaley  dw      0                       ;  for scaled y value
  282. curmode db      0                       ; screen mode before graphics
  283. tekgraf db      0               ; Tek graphics board selection (def=auto)
  284.                                 ; local variables for LINE plotting routine
  285. graph_mode db   0                       ; graphics video mode, default is none
  286. cursor  dw      0                       ; saved text cursor
  287. inited  db      0                       ; non-zero if inited (retains page)
  288. tekflg  db      0                       ; Tek mode active flag
  289. yflags  db      0                       ; flags byte from msy
  290. flow    dw      0                       ; flow control word
  291. gpage   db      0                       ; display adapter graphics page
  292. gfcol   db      15                      ; graphics foreground colour
  293. gbcol   db      0                       ; graphics background color
  294. tfcol   db      0                       ; temp foreground color
  295. tbcol   db      0                       ; temp background color
  296. lastd   db      0,0                     ; worker for ESC [ Pn ; Pn m scanner
  297. colortb db      0,4,2,6,1,5,3,7         ; color reversed-bit setting bytes
  298. moremsg db      ' More >'
  299. mormsglen equ   $-moremsg               ; length of message
  300. ccode   db      0                       ; temp for holding plot color code
  301. linelen dw      0                       ; offset increment between scan lines
  302. putc    dw      mputc                   ; ptr to plot a character routine
  303. psetup  dw      psetupm                 ; ptr to plot setup routine
  304. pincy   dw      pincym                  ; ptr to inc y routine
  305. plotptr dw      pltmon                  ; ptr to dot plot routine
  306. gcplot  dw      gcgen                   ; ptr to char plot routine
  307. segscn  dw      0b800h                  ; actual screen segment to use
  308.                                         ; ANSI Escape sequence to exit Tek mode
  309. tkoff   db      escape,'[?38l'          ; Exit Tek mode escape sequence
  310. tkofflen equ    $-tkoff                 ; length of sequence
  311. tkoffs  db      6 dup (0)               ; received chars in rcv'd sequence
  312. tkcnt   dw      0                       ; counter of matched char in tkoffs
  313. bypass  db      0                       ; GIN mode bypass condition (0=off)
  314. temp    dw      0
  315.  
  316. ; 8*8 font for Hercules and such, CGA, and EGA
  317. ; - allows 43 lines, and 80 (90 for Hercules) chars per line.
  318. ; all printing (?) characters from <space> to <del> - two characters per line
  319. ; 8 bits per scan line, given top line first, 8 scan lines.
  320. font    db      0,0,0,0,0,0,0,0,               18h,18h,18h,18h,18h,0,18h,0
  321.         db      6ch,6ch,6ch,0,0,0,0,0,         36h,36h,7fh,36h,7fh,36h,36h,0
  322.         db      0ch,3fh,68h,3eh,0bh,7eh,18h,0, 60h,66h,0ch,18h,30h,66h,06h,0
  323.         db      38h,6ch,6ch,38h,6dh,66h,3bh,0, 0ch,18h,30h,0,0,0,0,0
  324.         db      0ch,18h,30h,30h,30h,18h,0ch,0, 30h,18h,0ch,0ch,0ch,18h,30h,0
  325.         db      0,18h,7eh,3ch,7eh,18h,0,0,     0,18h,18h,7eh,18h,18h,0,0
  326.         db      0,0,0,0,0,18h,18h,30h,         0,0,0,7eh,0,0,0,0
  327.         db      0,0,0,0,0,18h,18h,0,           0,06h,0ch,18h,30h,60h,0,0
  328.         db      3ch,66h,6eh,7eh,76h,66h,3ch,0, 18h,38h,18h,18h,18h,18h,7eh,0
  329.         db      3ch,66h,06h,0ch,18h,30h,7eh,0, 3ch,66h,06h,1ch,06h,66h,3ch,0
  330.         db      0ch,1ch,3ch,6ch,7eh,0ch,0ch,0, 7eh,60h,7ch,06h,06h,66h,3ch,0
  331.         db      1ch,30h,60h,7ch,66h,66h,3ch,0, 7eh,06h,0ch,18h,30h,30h,30h,0
  332.         db      3ch,66h,66h,3ch,66h,66h,3ch,0, 3ch,66h,66h,3eh,06h,0ch,38h,0
  333.         db      0,0,18h,18h,0,18h,18h,0,       0,0,18h,18h,0,18h,18h,30h
  334.         db      0ch,18h,30h,60h,30h,18h,0ch,   0,0,0,7eh,0,7eh,0,0,0
  335.         db      30h,18h,0ch,06h,0ch,18h,30h,   0,3ch,66h,0ch,18h,18h,0,18h,0
  336.         db      3ch,66h,6eh,6ah,6eh,60h,3ch,   0,3ch,66h,66h,7eh,66h,66h,66h,0
  337.         db      7ch,66h,66h,7ch,66h,66h,7ch,   0,3ch,66h,60h,60h,60h,66h,3ch,0
  338.         db      78h,6ch,66h,66h,66h,6ch,78h,   0,7eh,60h,60h,7ch,60h,60h,7eh,0
  339.         db      7eh,60h,60h,7ch,60h,60h,60h,   0,3ch,66h,60h,6eh,66h,66h,3ch,0
  340.         db      66h,66h,66h,7eh,66h,66h,66h,   0,7eh,18h,18h,18h,18h,18h,7eh,0
  341.         db      3eh,0ch,0ch,0ch,0ch,6ch,38h,   0,66h,6ch,78h,70h,78h,6ch,66h,0
  342.         db      60h,60h,60h,60h,60h,60h,7eh,   0,63h,77h,7fh,6bh,6bh,63h,63h,0
  343.         db      66h,66h,76h,7eh,6eh,66h,66h,   0,3ch,66h,66h,66h,66h,66h,3ch,0
  344.         db      7ch,66h,66h,7ch,60h,60h,60h,   0,3ch,66h,66h,66h,6ah,6ch,36h,0
  345.         db      7ch,66h,66h,7ch,6ch,66h,66h,   0,3ch,66h,60h,3ch,06h,66h,3ch,0
  346.         db      7eh,18h,18h,18h,18h,18h,18h,   0,66h,66h,66h,66h,66h,66h,3ch,0
  347.         db      66h,66h,66h,66h,66h,3ch,18h,   0,63h,63h,6bh,6bh,7fh,77h,63h,0
  348.         db      66h,66h,3ch,18h,3ch,66h,66h,   0,66h,66h,66h,3ch,18h,18h,18h,0
  349.         db      7eh,06h,0ch,18h,30h,60h,7eh,   0,7ch,60h,60h,60h,60h,60h,7ch,0
  350.         db      0,60h,30h,18h,0ch,06h,0,0,     3eh,06h,06h,06h,06h,06h,3eh,0
  351.         db      18h,3ch,66h,42h,0,0,0,0,       0,0,0,0,0,0,0,0ffh
  352.         db      30h,18h,0ch,0,0,0,0,0,         0,0,3ch,06h,3eh,66h,3eh,0
  353.         db      60h,60h,7ch,66h,66h,66h,7ch,0, 0,0,3ch,66h,60h,66h,3ch,0
  354.         db      06h,06h,3eh,66h,66h,66h,3eh,0, 0,0,3ch,66h,7eh,60h,3ch,0
  355.         db      0eh,18h,18h,3ch,18h,18h,18h,0, 0,0,3eh,66h,66h,3eh,06h,3ch
  356.         db      60h,60h,7ch,66h,66h,66h,66h,0, 18h,0,38h,18h,18h,18h,3ch,0
  357.         db      18h,0,38h,18h,18h,18h,18h,70h, 60h,60h,66h,6ch,78h,6ch,66h,0
  358.         db      38h,18h,18h,18h,18h,18h,3ch,0, 0,0,76h,7fh,6bh,6bh,63h,0
  359.         db      0,0,7ch,66h,66h,66h,66h,0,     0,0,3ch,66h,66h,66h,3ch,0
  360.         db      0,0,7ch,66h,66h,7ch,60h,60h,0, 0,3eh,66h,66h,3eh,06h,07h
  361.         db      0,0,6ch,76h,60h,60h,60h,0,     0,0,3eh,60h,3ch,06h,7ch,0
  362.         db      30h,30h,7ch,30h,30h,30h,1ch,0, 0,0,66h,66h,66h,66h,3eh,0
  363.         db      0,0,66h,66h,66h,3ch,18h,0,     0,0,63h,6bh,6bh,7fh,36h,0
  364.         db      0,0,66h,3ch,18h,3ch,66h,0,     0,0,66h,66h,66h,3eh,06h,3ch
  365.         db      0,0,7eh,0ch,18h,30h,7eh,0,     0ch,18h,18h,70h,18h,18h,0ch,0
  366.         db      18h,18h,18h,0,18h,18h,18h,0,   30h,18h,18h,0eh,18h,18h,30h,0
  367.         db      31h,6bh,46h,0,0,0,0,0,         8 dup (0ffh)
  368. datas   ends
  369.  
  370. code    segment public 'code'
  371.         extrn   outchr:near, beep:near, scrseg:near, cmblnk:near
  372.         extrn   clrmod:near, savescr:near, cptchr:near, pcwait:near
  373.         extrn   restscr:near, getflgs:near, clrbuf:near, vtans52:near
  374.         extrn   iseof:near, beep:near
  375.         assume  cs:code, ds:datas, es:nothing
  376.  
  377. ; Initialise TEK mode by setting high resolution screen, etc
  378.  
  379. tekini  PROC NEAR
  380.         push    ax                      ; do presence tests
  381.         push    bx
  382.         push    cx
  383.         push    dx
  384.         push    si
  385.         push    di
  386.         push    es
  387.         mov     bx,portval              ; get port flow control chars:
  388.         mov     bx,[bx].flowc           ; bh=xon, bl=xoff or both are nulls
  389.         mov     flow,bx                 ; save here
  390.         mov     ax,bx                   ; get flow control word
  391.         cmp     al,0                    ; able to do xoff?
  392.         je      tekin0                  ; e = no
  393.         call    outmodem                ; tell host xoff while we change modes
  394. tekin0: mov     bx,vtemu.att_ptr        ; emulator screen color ptr
  395.         mov     al,[bx]
  396.         mov     gfcol,al                ; save foreground color
  397.         and     gfcol,0fh               ; save just foreground bits
  398.         and     al,70h                  ; select background color, no bold
  399.         mov     cl,4
  400.         shr     al,cl                   ; get background colors
  401.         mov     gbcol,al                ; set graphics background color
  402.         mov     ah,15                   ; get current screen mode
  403.         int     screen
  404.         cmp     al,3                    ; in a mono/color text mode (2/3)?
  405.         jbe     tekin1                  ; be = yes
  406.         cmp     al,mono                 ; mono text mode (7)?
  407.         je      tekin1                  ; e = yes
  408.         cmp     tekflg,0                ; are we active as Tek device now?
  409.         je      tekin1                  ; e = no
  410.         jmp     tekin13                 ; yes, don't redo graphics setup
  411. tekin1: mov     curmode,al              ; save mode here
  412.         mov     ah,3                    ; get cursor position
  413.         xor     bh,bh                   ; page 0
  414.         int     screen
  415.         mov     cursor,dx               ; save position
  416.         call    savescr                 ; save text screen
  417.                                         ; Presence tests.
  418. tekin2: mov     graph_mode,cga          ; Color. Assume CGA
  419.         mov     segscn,segcga           ; assume cga screen segment
  420.         mov     gpage,0                 ; graphics page 0 but no page 1
  421.         mov     putc,offset gputc       ; CGA character display routine
  422.         mov     gcplot,offset gcgen     ; General character plot routine
  423.         mov     psetup,offset psetupc   ; CGA plot setup routine
  424.         mov     plotptr,offset pltcga   ; CGA dot plot routine
  425.         mov     pincy,offset pincyc     ; CGA inc y routine
  426.         mov     xmult,5                 ; CGA. Scale TEK to PC by 640/1024
  427.         mov     xdiv,8                  ;  so that 0-1023 converts to 0-639
  428.         mov     xmax,640-8              ; x-coord of rightmost character
  429.         mov     ymult,10                ; vertical scale for IBM is 200/780
  430.         mov     ydiv,39                 ;
  431.         mov     ybot,199                ; Bottom of screen is Y=199
  432.         mov     al,tekgraf              ; user video board specification
  433.         cmp     al,0                    ; auto-sensing?
  434.         je      tekin2c                 ; e = yes (default)
  435.         cmp     al,1                    ; user wants CGA?
  436.         jne     tekin2a                 ; ne = no
  437.         jmp     tekin13                 ; do CGA
  438. tekin2a:cmp     al,4                    ; user wants Hercules?
  439.         jne     tekin2b                 ; ne = no
  440.         jmp     tekin8                  ; do Hercules
  441. tekin2b:cmp     al,5                    ; user wants AT&T style?
  442.         jne     tekin2c                 ; ne = no
  443.         jmp     tekin7                  ; do AT&T kind
  444.                                         ; do auto-sensing of display board
  445.                                         ; test for EGA
  446. tekin2c:mov     ax,1200H                ; EGA: Bios alternate select
  447.         mov     bl,10H                  ; Ask for EGA info
  448.         mov     bh,0ffH                 ; Bad info, for testing
  449.         mov     cl,0fH                  ; Reserved switch settings
  450.         int     screen                  ; EGA, are you there?
  451.         and     cl,0fh                  ; four lower switches
  452.         cmp     cl,0cH                  ; Test reserved switch settings
  453.         jb      tekin3                  ; b = ega present
  454.         jmp     tekin7                  ; else no EGA, check other adapters
  455.  
  456. tekin3: mov     ax,40h                  ; check Bios 40:87h for ega being
  457.         mov     es,ax                   ;  the active display adapter
  458.         test    byte ptr es:[87h],8     ; is ega active?
  459.         jz      tekin3a                 ; z = yes
  460.         jmp     tekin7                  ; ega is inactive, check others
  461. tekin3a:cmp     bl,1                    ; is there 128KB on ega board?
  462.         jb      tekin4                  ; b = less, so no screen saves
  463.         mov     gpage,1                 ; >=128 KB, use two graphics pages
  464. tekin4: mov     graph_mode,ega          ; assume high resolution color
  465.         cmp     cl,3                    ; high resolution color?
  466.         je      tekin5                  ; e = yes
  467.         cmp     cl,9                    ; high resolution color?
  468.         je      tekin5                  ; e = yes
  469.         mov     graph_mode,monoega      ; assume mono monitor on ega board
  470.         test    bh,1                    ; ega mono mode in effect?
  471.         jnz     tekin5                  ; nz = yes
  472.         mov     graph_mode,colorega     ; say ordinary cga on ega board, 64KB
  473.         mov     gpage,1                 ; is enough memory with 200 scan lines
  474.         jmp     short tekin5a           ; use current cga parameters
  475. tekin5: mov     ybot,349                ; text screen bottom is 349 on EGA
  476.         mov     ymult,35                ;
  477.         mov     ydiv,78                 ; scale y by 350/780
  478. tekin5a:mov     segscn,segega           ; use ega screen segment
  479.         mov     psetup,offset psetupe   ; plot setup routine
  480.         mov     plotptr,offset pltega   ; ega dot plot routine
  481.         mov     pincy,offset pincye     ; inc y routine
  482.         mov     putc,offset gputc       ; character display routine
  483.         mov     gcplot,offset gcega     ; EGA character plot routine
  484.         call    fixcolor                ; correct color mapping for some bds
  485.         jmp     tekin13                 ; end of EGA part, do VGA tests below
  486.  
  487. tekin7: mov     ax,0fc00h               ; Olivetti/AT&T 6300, check rom id
  488.         mov     es,ax
  489.         mov     di,0                    ; start here
  490.         mov     graph_mode,olivetti     ; Olivetti
  491.         mov     cx,attlen               ; length of logo
  492.         mov     si,offset ATTLOGO       ; master string
  493.         repe    cmpsb                   ; do a match
  494.         je      tekin7c                 ; e = a match
  495.         mov     di,0050h                ; look here too
  496.         mov     si,offset ATTLOGO
  497.         mov     cx,attlen
  498.         repe    cmpsb
  499.         je      tekin7c                 ; e = a match
  500.         mov     di,2014h                ; and look here
  501.         mov     si,offset ATTLOGO
  502.         mov     cx,attlen
  503.         repe    cmpsb                   ; do a match
  504.         je      tekin7c                 ; e = a match, else try other types
  505. tekin7a:mov     graph_mode,toshiba
  506.         mov     ax,0f000h               ; Check for Toshiba T3100, rom scan
  507.         mov     es,ax
  508.         mov     di,0014h                ; start here
  509.         mov     si,offset TOSHLOGO      ; master string
  510.         mov     cx,toshlen              ; length
  511.         repe    cmpsb                   ; do a match
  512.         je      tekin7c                 ; e = a match, else try other types
  513. tekin7b:mov     graph_mode,vaxmate      ; DEC VAXmate II
  514.         mov     ax,0f000h               ; Check for VAXmate II rom signature
  515.         mov     es,ax
  516.         mov     di,0e000h               ; start here
  517.         mov     si,offset DECLOGO       ; master string
  518.         mov     cx,declen               ; length
  519.         repe    cmpsb                   ; do a match
  520.         jne     tekin7d                 ; ne = mismatch, try other types
  521.  
  522.                                         ; Olivetti/AT&T, Toshiba, VAXmate
  523. tekin7c:mov     gpage,0                 ; only page 0 with 640 by 400 mode
  524.         mov     segscn,segcga           ; use cga screen segment (0b800h)
  525.         mov     psetup,offset psetupo   ; plot setup routine
  526.         mov     plotptr,offset pltcga   ; cga dot plot routine
  527.         mov     pincy,offset pincyh     ; inc y routine (Herc style addresses)
  528.         mov     putc,offset gputc       ; character display routine
  529.         mov     gcplot,offset gcgen     ; General character plot routine
  530.         mov     ybot,399                ; bottom of screen is y = 399
  531.         mov     ymult,20                ; vertical scale = 400/780
  532.         mov     ydiv,39                 ; same as cga setup
  533.         jmp     tekin13
  534.  
  535. tekin7d:cmp     curmode,mono            ; mono text mode?
  536.         je      tekin8                  ; e = yes
  537.         jmp     tekin11                 ; ne = no, try cga
  538.                                         ; test for Hercules
  539. tekin8: call    scrseg                  ; get screen segment, test Environment
  540.         cmp     tv_mode,0               ; Environment active?
  541.         je      tekin8a                 ; e = no, ok to test for Hercules
  542.         jmp     tekin10                 ; don't do Herc mode, do Mono
  543. tekin8a:mov     dx,hstatus              ; Herc status port
  544.         in      al,dx                   ; read it
  545.         mov     bl,al                   ; save here
  546.         and     bl,80h                  ; remember retrace bit
  547.         mov     cx,0ffffh               ; do many times (for fast machines)
  548. tekin8b:mov     dx,hstatus              ; check status port
  549.         in      al,dx
  550.         and     al,80h                  ; select bit
  551.         jmp     $+2                     ; use a little time
  552.         cmp     bl,al                   ; did it change?
  553.         loope   tekin8b                 ; test again if not
  554.         je      tekin10                 ; e = no change in bit, not Herc
  555.         mov     graph_mode,hercules     ; say have Herc board
  556.         mov     segscn,seghga           ; assume hga screen segment
  557.         mov     putc,offset gputc       ; character display routine
  558.         mov     gcplot,offset gcgen     ; General character plot routine
  559.         mov     psetup,offset psetuph   ; plot setup routine to use
  560.         mov     plotptr,offset pltcga   ; use cga dot plot routine for Herc
  561.         mov     pincy,offset pincyh     ; inc y routine
  562.         mov     xmult,45                ; Scale TEK to Hercules by 720/1024
  563.         mov     xdiv,64                 ;  so that 0-1023 converts to 0-719
  564.         mov     xmax,720-8              ; x-coord of rightmost character
  565.         mov     ymult,87                ; vertical scale for Hercules is
  566.         mov     ydiv,195                ;  348/780
  567.         mov     ybot,347                ; bottom of screen is y = 347
  568.         mov     ax,seghga               ; segment of Herc video display
  569.         mov     es,ax
  570.         mov     al,es:[8000h]           ; read original contents, page 1
  571.         not     byte ptr es:[8000h]     ; write new pattern
  572.         mov     ah,es:[8000h]           ; read back
  573.         not     byte ptr es:[8000h]     ; restore original contents
  574.         not     ah                      ; invert this too
  575.         cmp     ah,al                   ; same (memory present?)
  576.         jne     tekin9                  ; ne = not same, no memory there
  577.         mov     gpage,1                 ; say two pages of display memory
  578. tekin9: jmp     tekin13
  579.                                         ; set to MONO
  580. tekin10:mov     graph_mode,mono         ; force monochrome adapter text
  581.         mov     segscn,segmono          ; assume mono screen segment
  582.         call    scrseg                  ; Environments: get virtual screen
  583.         mov     segscn,ax               ;  seg returned in ax and es:di
  584.         mov     gpage,0
  585.         mov     putc,offset mputc       ; character display routine
  586.         mov     psetup,offset psetupm   ; plot setup routine to use
  587.         mov     plotptr,offset pltmon   ; use hga dot plot routine
  588.         mov     pincy,offset pincym     ; inc y routine
  589.         mov     xmult,5                 ; Scale TEK to mono by 640/1024
  590.         mov     xdiv,8                  ;  so that 0-1023 converts to 0-639
  591.         mov     xmax,640-8              ; x-coord of rightmost character
  592.         mov     ymult,10                ; vertical scale for mono is 200/780
  593.         mov     ydiv,39
  594.         mov     ybot,200                ; bottom of screen is y = 200 for Bios
  595.         jmp     tekin13                 ; Uses TEXT mode, for safety
  596.  
  597.                                         ; test for CGA
  598. tekin11:mov     graph_mode,cga          ; set CGA high resolution graphics
  599.         mov     segscn,segcga           ; CGA screen segment
  600.         jmp     tekin13
  601.  
  602.                                         ; Set Graphics mode
  603. tekin13:cmp     graph_mode,hercules     ; Hercules?
  604.         jne     tekin14                 ; ne = no
  605.         call    hgraf                   ; set Herc graphics mode, clear regen
  606.         jmp     short tekin16           ; restore screen
  607. tekin14:mov     ah,0                    ; set screen mode
  608.         mov     al,graph_mode           ;  to this screen mode
  609.         cmp     tekgraf,3               ; user wants "VGA" modes (640x480)?
  610.         jne     tekin14a                ; ne = no
  611.         cmp     al,monoega              ; yes, allow high resolution stuff?
  612.         jb      tekin14a                ; b = no
  613.         cmp     al,ega                  ; ditto
  614.         ja      tekin14a                ; a = no
  615.         add     al,2                    ; use modes 17(b/w) and 18(10)(color)
  616.         mov     ybot,479                ; text screen bottom is 479 on VGA
  617.         mov     ymult,48
  618. tekin14a:cmp    gpage,0                 ; only page 0 available?
  619.         je      tekin15                 ; e = yes, and watch for Bios errors
  620.         cmp     inited,0                ; first time through?
  621.         je      tekin15                 ; e = yes, clear the page of old junk
  622.         or      al,80h                  ; save regen buffer (save area too)
  623. tekin15:int     screen                  ; Bios Set Mode.
  624.  
  625. tekin16:mov     tekflg,1                ; starting Tek sub mode
  626.         cmp     inited,0                ; inited yet?
  627.         jne     tekin19                 ; ne = yes, restore screen
  628.         mov     ttstate,offset tektxt   ; do displayable text
  629.         mov     prestate,offset tektxt  ; set a previous state of text
  630.         mov     inited,1                ; say we have initialized
  631.         mov     al,gfcol
  632.         mov     tfcol,al                ; remember current coloring
  633.         mov     al,gbcol
  634.         mov     tbcol,al
  635.         call    tekcls                  ; clear screen, for ega coloring
  636.         jmp     short tekin20
  637. tekin19:call    tekrest                 ; restore old graphics screen
  638.         mov     al,tfcol                ; and coloring
  639.         mov     gfcol,al
  640.         mov     al,tbcol
  641.         mov     gbcol,al
  642. tekin20:mov     ax,flow                 ; get flow control word
  643.         xchg    ah,al                   ; get xon into al
  644.         cmp     al,0                    ; able to send xon?
  645.         je      tekin21                 ; e = no
  646.         call    outmodem                ; tell host xon
  647. tekin21:clc                             ; clear carry for success
  648.         jmp     short tekin23
  649. tekin22:stc                             ; set carry for failure
  650. tekin23:pop     es
  651.         pop     di
  652.         pop     si
  653.         pop     dx
  654.         pop     cx
  655.         pop     bx
  656.         pop     ax
  657.         ret
  658. tekini  ENDP
  659.  
  660. TEKRINT proc    near                    ; Tek reinitialization entry point
  661.         mov     inited,0                ; do complete reinitialization
  662.         jmp     tekini
  663. TEKRINT endp
  664.  
  665. ;Terminal emulation. Enter with received character in AL.
  666.  
  667. TEKEMU PROC     NEAR                    ; main emulator
  668.         cmp     tekflg,0                ; Tek mode active yet? (msz call)
  669.         jne     tektt1                  ; ne = yes
  670.         call    tekini                  ; init now
  671.         mov     ttstate,offset tektxt   ; initial state
  672.         mov     prestate,offset tektxt  ; set a previous state of text
  673.         jnc     tektt1                  ; nc = succeeded
  674.         ret                             ; else failed to init, just return
  675. tektt1: and     al,7fh                  ; force Tek chars to be 7 bits
  676.         cmp     al,0                    ; NUL char?
  677.         je      tekign                  ; e = yes, ignore it before logging
  678.         push    ax
  679.         call    getflgs                 ; get msy yflags into al
  680.         mov     yflags,al
  681.         test    al,capt                 ; capturing output?
  682.         pop     ax
  683.         jz      tektt4                  ; z = no, forget this part
  684.         push    ax                      ; save char
  685.         call    cptchr                  ; give it captured character
  686.         pop     ax                      ; restore character and keep going
  687. tektt4: test    yflags,trnctl           ; debug? if so use tty mode
  688.         jz      tektt5                  ; z = no
  689.         cmp     al,DEL                  ; DEL char?
  690.         jne     tektt4a                 ; ne = no
  691.         mov     al,5eh                  ; make DEL a caret query mark
  692.         call    outscrn
  693.         mov     al,3fh                  ; the query mark
  694.         call    outscrn
  695.         jmp     short tekign
  696. tektt4a:cmp     al,' '                  ; control char?
  697.         jae     tektt4b                 ; ne = no
  698.         push    ax
  699.         mov     al,5eh                  ; caret
  700.         call    outscrn
  701.         pop     ax
  702.         add     al,'A'-1                ; make char printable
  703. tektt4b:call    outscrn
  704.  
  705. tekign: ret                             ; Ignore this character
  706.  
  707. tektt5: call    tkscan                  ; scan for "ESC [ ? 3 8 l" exit code
  708. tektt5a:cmp     al,0                    ; null char response?
  709.         je      tekign                  ; e = yes, ignore the character
  710.         cmp     al,' '                  ; control code?
  711.         jb      tektt6                  ; b = yes, decode
  712.         jmp     ttstate                 ; no, do current state
  713.                                         ; Control characters:
  714. tektt6: cmp     al,GS                   ; Line plot command?
  715.         jne     tektt7                  ; ne = no
  716.         mov     visible,0               ; Next move is invisible
  717.         and     status,not txtmode      ; set status report byte
  718.         mov     ttstate,offset tekline  ; expect coordinates next
  719.         jmp     tektt12
  720. tektt7: cmp     al,RS                   ; Incremental dot command?
  721.         jne     tektt8                  ; ne = no
  722.         and     status,not txtmode      ; set status report
  723.         mov     ttstate,offset tekrlin  ; expect pen command next
  724.         jmp     tektt12
  725. tektt8: cmp     al,FS                   ; Point plot command?
  726.         jne     tektt9                  ; ne = no
  727.         mov     visible,0               ; next move is invisible
  728.         and     status,not txtmode      ; set status report byte
  729.         mov     ttstate,offset tekpnt
  730.         jmp     tektt12
  731. tektt9: cmp     al,US                   ; assert text mode? [bjh]
  732.         jne     tektt10                 ; ne = no
  733.         or      status,txtmode          ; set status report byte
  734.         mov     ttstate,offset tektxt   ; Go to TEKTXT next time
  735.         mov     bypass,0                ; reset bypass condition
  736.         jmp     tektt12
  737. tektt10:cmp     al,ESCAPE               ; Escape?
  738.         jne     tektt11                 ; ne = no
  739.         or      status,txtmode          ; set status report byte
  740.         cmp     ttstate,offset tekesc   ; already in escape state?
  741.         je      tektt14                 ; e = yes, nest no further
  742.         push    ttstate                 ; current state
  743.         pop     prestate                ; save here as previous state
  744.         mov     ttstate,offset tekesc   ; next state parses escapes
  745.         ret
  746. tektt11:cmp     al,CAN                  ; Control X? (exits Tek sub mode)
  747.         jne     tektt13                 ; ne = no, stay in current state
  748.         cmp     ttstate,offset tekesc   ; ESC Control-X?
  749.         je      tektt13                 ; yes, parse it in tekesc code
  750.         mov     ttstate,offset tektxt   ; back to text mode
  751.         test    flags.vtflg,tttek       ; main Tek emulator?
  752.         jnz     tektt12                 ; nz = yes, ignore the ^X
  753.         call    tekend                  ; else exit sub mode
  754.         mov     tekflg,0                ; clear Tek sub mode flag
  755. tektt12:mov     prestate,offset tektxt  ; make previous state text
  756. tektt14:ret
  757. tektt13:jmp     ttstate                 ; let someone else worry about this
  758. TEKEMU  ENDP
  759.  
  760. ; End TEK emulation, recover previous screen
  761.  
  762. TEKEND  PROC    NEAR
  763.         cmp     tekflg,0                ; Tek sub mode active?
  764.         jne     teknd0                  ; ne = yes
  765.         ret                             ; else return as is.
  766. teknd0: call    teksave                 ; save graphics screen to page 1
  767.         cmp     graph_mode,hercules     ; Hercules?
  768.         jne     teknd1                  ; ne = no
  769.         call    htext                   ; yes then set up Hercules text mode
  770. teknd1: mov     ah,0                    ; set video mode
  771.         mov     al,curmode              ; restore previous screen mode
  772.         int     screen                  ; revert to text screen
  773.         call    restscr                 ; restore text screen
  774.         mov     dx,cursor               ; saved cursor position
  775.         mov     bh,0                    ; page 0
  776.         mov     ah,2                    ; set cursor
  777.         int     screen
  778.         ret
  779. TEKEND  ENDP
  780.  
  781. ; State machine active while Tek is active. Senses ESC [ ? 3 8 l to exit
  782. ; Tek mode and return to either non-sub mode terminal or to a VT102.
  783. ; Plays back unmatched escape sequences. Enter with character in al.
  784.  
  785. tkscan  proc    near
  786.         and     al,7fh                  ; strip high bit
  787.         cmp     al,byte ptr tkoff       ; start of Tek Off sequence?
  788.         jne     tkscn1                  ; ne = no
  789.         call    tkscn4                  ; playback previously matched chars
  790.         mov     tkcnt,1                 ; count matched chars (one now)
  791.         mov     tkoffs,al               ; save full character, with high bit
  792.         mov     al,0                    ; our temporary response
  793.         jmp     short tkscnx            ;  and exit
  794.  
  795. tkscn1: push    bx                      ; check for char in Tek Off sequence
  796.         mov     bx,tkcnt                ; number of chars matched in Tek Off
  797.         mov     tkoffs[bx],al           ; save this char
  798.         cmp     al,byte ptr tkoff[bx]   ; match expected char in sequence?
  799.         pop     bx
  800.         jne     tkscn3                  ; ne = no, play back partial match
  801.         inc     tkcnt                   ; count new match
  802.         mov     al,0                    ; our temporary response
  803.         cmp     tkcnt,tkofflen          ; matched all char in sequence?
  804.         jne     tkscnx                  ; ne = not yet, wait for more
  805.         mov     tkcnt,0                 ; clear counter
  806.         cmp     flags.vtflg,tttek       ; are we a full Tek terminal now?
  807.         jne     tkscn2                  ; ne = no, a submode
  808.         call    vtans52                 ; toggle terminal type, in msyibm
  809. tkscn2: mov     al,CAN                  ; simulate arrival of Control-X
  810.         jmp     short tkscnx            ;  all done
  811.  
  812. tkscn3: call    tkscn4                  ; playback previously matched chars
  813.         mov     tkcnt,0                 ; reset to no match and exit
  814. tkscnx: ret                             ; common exit
  815.  
  816.                                         ; local worker procedure
  817. tkscn4: push    ax                      ; save break char (in al)
  818.         push    cx                      ; playback partial sequence to screen
  819.         mov     cx,tkcnt                ; number of chars matched before break
  820.         jcxz    tkscn4b                 ; z = none
  821.         push    si
  822.         mov     si,offset tkoffs        ; string to be played back
  823. tkscn4a:cld
  824.         lodsb                           ; get a char into al
  825.         push    cx
  826.         push    si                      ; save these around tektt5a work
  827.         call    tektt5a                 ; use it
  828.         pop     si
  829.         pop     cx
  830.         loop    tkscn4a                 ; do all that came in previously
  831.         pop     si
  832. tkscn4b:pop     cx
  833.         pop     ax                      ; recover break char
  834.         ret
  835. tkscan  endp
  836.  
  837.  
  838. TEKTXT  proc    near                    ; Dispatch on text characters
  839.         cmp     al,DEL                  ; RUBOUT?
  840.         jne     tektx1                  ; ne = no
  841.         mov     al,bs                   ; make BS
  842.         jmp     short tektx7
  843. tektx1: cmp     al,CR                   ; carriage return (^M)?
  844.         je      tektx9                  ; e = yes
  845. tektx2: cmp     al,LF                   ; line feed (^J)?
  846.         je      tektx9                  ; e = yes
  847. tektx3: cmp     al,FF                   ; form feed (^L)?
  848.         jne     tektx4                  ; ne = no
  849.         call    tekcls                  ; clear the screen
  850.         jmp     short tektx8
  851. tektx4: cmp     al,VT                   ; vertical tab (^K)?
  852.         je      tektx7
  853.         cmp     al,bell                 ; bell (^G)?
  854.         jne     tektx5                  ; ne = no
  855.         call    beep
  856.         mov     bypass,0                ; clear GIN mode bypass condition
  857.         jmp     short tektx8
  858. tektx5: cmp     al,tab                  ; horizontal tab (^I)?
  859.         je      tektx7                  ; e = yes
  860. tektx6: cmp     al,BS                   ; backspace (^H)?
  861.         je      tektx7                  ; e = yes
  862.         cmp     al,' '                  ; control char?
  863.         jb      tektx8                  ; b = yes, ignore it
  864. tektx7: cmp     bypass,0                ; bypass mode off?
  865.         jne     tektx8                  ; ne = no, it's on so skip display
  866.         call    OUTSCRN                 ; output character to the screen
  867. tektx8: ret
  868. tektx9: mov     bypass,0                ; clear GIN mode bypass condition
  869.         jmp     short tektx7
  870. TEKTXT  endp
  871.  
  872. ; Process escape sequences. Callable from msz terminal emulator.
  873. ; Enter with received character in AL. Escape sequences are generally
  874. ; treated as interruptions to the current plotting/text command. Screen
  875. ; clearing is the exception by causing a general emulator reset.
  876. TEKESC  PROC    NEAR
  877.         mov     bypass,0                ; clear GIN mode bypass condition
  878.         mov     ttstate,offset tekesc   ; in case get here from msz file
  879.         cmp     tekflg,0                ; Tek mode active yet? (msz call)
  880.         jne     tekesc1                 ; ne = yes
  881.         call    tekini                  ; init now
  882.         mov     prestate,offset tektxt  ; set a previous state of text
  883.         jnc     tekesc1                 ; nc = succeeded
  884.         ret                             ; else failed to init, just return
  885.  
  886. tekesc1:cmp     al,'Z'                  ; ESC-Z Identify?
  887.         jne     tekesc2                 ; ne = no
  888.         call    SENDID                  ; Send terminal identification
  889.         jmp     tekescx
  890.  
  891. tekesc2:cmp     al,FF                   ; ESC-FF Clear screen?
  892.         jne     tekesc3                 ; ne = no
  893.         call    tekcls                  ; Clear screen
  894.         mov     prestate,offset tektxt  ; make previous state text mode
  895.         jmp     tekescx                 ; Return to text mode after ESC-FF
  896.  
  897. tekesc3:cmp     al,ESCZ                 ; ESC-^Z Enter GIN mode?
  898.         jne     tekesc4                 ; ne = no
  899.         cmp     graph_mode,mono         ; Monochrome text mode?
  900.         je      tekesc3a                ; e = yes, no crosshairs in text mode
  901.         mov     bypass,1                ; turn on GIN mode bypass conditon
  902.         call    CROSHAIR                ; Activate the cross-hairs
  903.         jmp     tekescx
  904. tekesc3a:call   beep                    ; tell the user we are unhappy
  905.         jmp     tekescx                 ; and ignore the command
  906.  
  907. tekesc4:cmp     al,ENQ                  ; ESC-^E Enquiry for cursor position?
  908.         jne     tekesc5                 ; ne = no
  909.         mov     bypass,1                ; set bypass mode
  910.         call    SENDSTAT                ; send status
  911.         jmp     tekescx
  912.  
  913. tekesc5:cmp     al,CAN                  ; ESC Control-X?
  914.         jne     tekesc6                 ; ne = no
  915.         mov     bypass,1                ; set bypass condition
  916.         jmp     tekescx
  917.  
  918. tekesc6:cmp     al,3fh                  ; query mark? (ESC ? means DEL)
  919.         jne     tekesc7                 ; ne = no
  920.         mov     al,DEL                  ; replace with DEL code
  921.         jmp     tekescx                 ; and process it as if received.
  922.  
  923. tekesc7:cmp     al,accent               ; accent grave, line pattern series?
  924.         jb      tekesc8                 ; b = no
  925.         cmp     al,65h                  ; lowercase e?
  926.         ja      tekescx                 ; a = beyond line pattern series
  927.         push    bx
  928.         mov     bl,al
  929.         sub     bl,accent               ; remove bias
  930.         and     bl,7                    ; eight patterns, roll over excess
  931.         mov     bh,0
  932.         shl     bx,1                    ; make this a word index
  933.         mov     bx,linetab[bx]          ; get line pattern word
  934.         mov     linepat,bx              ; save in active word
  935.         pop     bx                      ; return to previous mode
  936.  
  937. tekesc8:cmp     al,5bh                  ; right square bracket?
  938.         jne     tekescx                 ; ne = no
  939.         jmp     tekcol                  ; start coloring scan
  940.  
  941. tekescx:push    ax
  942.         mov     ax,prestate             ; get previous state
  943.         mov     ttstate,ax              ; restore it
  944.         or      ax,ax                   ; test for none
  945.         pop     ax
  946.         jz      go2text                 ; z = none, use text mode
  947.         clc
  948.         ret                             ; resume previous state
  949.  
  950. go2text:mov     ttstate,offset tektxt   ; Go to TEKTXT next time
  951.         mov     lastc,0                 ; clear last drawing coordinate flag
  952.         or      status,txtmode          ; set text mode in status byte
  953.         clc
  954.         ret
  955. TEKESC  ENDP
  956. ; Parse ESC [ Pn ; Pn m
  957. ; where Pn = 30-37 foreground color, 40-47 background color, ANSI standard
  958. TEKCOL  proc    near
  959.         mov     word ptr lastd,0        ; clear parsing flags used below
  960.         mov     ttstate,offset tekco1   ; resume parsing below
  961.         clc
  962.         ret
  963. tekco1: cmp     lastd,'3'               ; units digit in 30 series?
  964.         jne     tekco2                  ; ne = no
  965.         inc     lastd+1                 ; count argument
  966.         sub     al,'0'                  ; ascii to binary
  967.         cmp     al,7                    ; numeric?
  968.         jbe     tekco1a                 ; be = yes
  969.         jmp     tekco10                 ; a = no, error
  970. tekco1a:push    bx
  971.         mov     bl,al
  972.         mov     bh,0
  973.         mov     al,byte ptr colortb[bx] ; reverse coloring
  974.         pop     bx
  975.         and     tfcol,not (7)           ; retain intensity bit
  976.         or      tfcol,al                ; remember foreground color
  977.         mov     lastd,0                 ; clear parsing flag
  978.         ret
  979.  
  980. tekco2: cmp     lastd,'4'               ; units digit in 40 series?
  981.         jne     tekco4                  ; ne = no
  982.         inc     lastd+1                 ; count argument
  983.         sub     al,'0'
  984.         cmp     al,7                    ; numeric?
  985.         ja      tekco10                 ; a = no, error
  986.         push    bx
  987.         mov     bl,al
  988.         mov     bh,0
  989.         mov     al,byte ptr colortb[bx] ; reverse coloring
  990.         pop     bx
  991.         mov     tbcol,al                ; remember background color
  992.         mov     lastd,0                 ; clear parsing flag
  993.         ret
  994.  
  995. tekco4: cmp     lastd,0                 ; looking for tens digit?
  996.         jne     tekco10                 ; ne = yes, error
  997.         cmp     al,';'                  ; separator?
  998.         jne     tekco5                  ; ne = no
  999.         ret                             ; ignore it
  1000.  
  1001. tekco5: cmp     al,'0'                  ; remove intensity, set b/w?
  1002.         jne     tekco6                  ; ne = no
  1003.         mov     tfcol,7                 ; regular white
  1004.         mov     tbcol,0                 ;  on black
  1005.         inc     lastd+1                 ; count argument
  1006.         ret
  1007.  
  1008. tekco6: cmp     al,'1'                  ; intensity bit?
  1009.         jne     tekco7                  ; ne = no
  1010.         and     tfcol,not (8)
  1011.         or      tfcol,8                 ; set foreground intensity
  1012.         inc     lastd+1                 ; count argument
  1013.         ret
  1014.  
  1015. tekco7: cmp     al,'m'                  ; end of sequence
  1016.         je      tekco8                  ; e = yes
  1017.         cmp     al,'3'
  1018.         jb      tekco10                 ; b = not allowed tens digit
  1019.         cmp     al,'4'
  1020.         ja      tekco10                 ; a = not allowed tens digit
  1021.         mov     lastd,al                ; remember tens digit
  1022.         inc     lastd+1                 ; count argument
  1023.         ret
  1024.  
  1025. tekco8: cmp     lastd+1,0               ; number of ansi arguments, zero?
  1026.         ja      tekco9                  ; a = no, got some
  1027.         mov     tbcol,0                 ; none is same as 0, set b/w
  1028.         mov     tfcol,7
  1029. tekco9: mov     al,tbcol                ; success, store coloring
  1030.         mov     gbcol,al                ; set background color
  1031.         mov     al,tfcol
  1032.         mov     gfcol,al                ; set foreground color
  1033. tekco10:mov     word ptr lastd,0        ; clear argument and number of args
  1034.         call    fixcolor                ; do special ega corrections
  1035.         mov     al,gfcol                ; update these in case error
  1036.         mov     tfcol,al
  1037.         mov     al,gbcol
  1038.         mov     tbcol,al
  1039.         jmp     tekescx                 ; finish escape state
  1040. TEKCOL  endp
  1041.  
  1042. ; Revise screen color codes for ega boards with mono displays and limited
  1043. ; memory.
  1044. fixcolor proc   near
  1045.         cmp     graph_mode,ega          ; one of these ega modes?
  1046.         je      fixcol0                 ; e = yes
  1047.         cmp     graph_mode,colorega
  1048.         je      fixcol0
  1049.         cmp     graph_mode,monoega
  1050.         je      fixcol0
  1051.         ret                             ; else ignore color corrections
  1052. fixcol0:mov     ah,gfcol
  1053.         mov     al,gbcol
  1054.         cmp     graph_mode,monoega      ; monochrome display?
  1055.         jne     fixcol3                 ; ne = no
  1056.         test    al,7                    ; bright backgound?
  1057.         jnz     fixcol1                 ; nz = yes
  1058.         mov     ah,1                    ; normal foreground
  1059.         test    gfcol,8                 ; intensity on?
  1060.         jz      fixcol1                 ; z = no
  1061.         mov     ah,5                    ; say bright foreground
  1062. fixcol1:test    al,7                    ; black backgound?
  1063.         jz      fixcol2                 ; z = yes
  1064.         mov     al,1                    ; regular video
  1065. fixcol2:cmp     ah,al                   ; same color in both?
  1066.         jne     fixcol3                 ; ne = no
  1067.         mov     ah,1                    ; make foreground regular
  1068.         mov     al,0                    ;  and background black
  1069. fixcol3:mov     gfcol,ah
  1070.         mov     gbcol,al
  1071.         cmp     gpage,0                 ; minimal memory (64KB mono and ega)?
  1072.         ja      fixcol4                 ; a = no, enough, else strange mapping
  1073.         mov     al,gfcol                ; fix coloring to map planes C0 to C1
  1074.         and     al,5                    ; and C2 to C3 (as 0, 3, 0Ch, or 0Fh)
  1075.         mov     ah,al                   ; make a copy
  1076.         shl     ah,1                    ; duplicate planes C0, C2 in C1, C3
  1077.         or      al,ah                   ; merge the bits
  1078.         mov     gfcol,al                ; store proper foreground color
  1079.         mov     al,gbcol                ; repeat for background color
  1080.         and     al,5
  1081.         mov     ah,al
  1082.         shl     ah,1
  1083.         or      al,ah
  1084.         mov     gbcol,al
  1085. fixcol4:ret
  1086. fixcolor endp
  1087.  
  1088. TEKLINE proc    near                    ; GS line drawing
  1089.         call    tekxyc                  ; parse coordinates from input bytes
  1090.         jnc     teklin1                 ; nc = not done yet
  1091.         mov     cl,visible              ; get moveto or drawto variable
  1092.         call    tekdraw                 ; move that point
  1093.         mov     visible,1               ; say next time we draw
  1094. teklin1:ret
  1095. TEKLINE endp
  1096.  
  1097. TEKPNT  proc    near                    ; FS plot single point
  1098.         call    tekxyc                  ; parse coordinates
  1099.         jnc     tekpnt1                 ; nc = not done yet
  1100.         mov     cl,0                    ; do not draw
  1101.         call    tekdraw                 ; move to the point
  1102.         mov     ax,si                   ; copy starting point to end point
  1103.         mov     bx,di                   ; ax,bx,si,di are in PC coordinates
  1104.         mov     cl,1                    ; make plot visible
  1105.         call    line                    ; draw the dot
  1106.         mov     visible,0               ; return to invisibility
  1107. tekpnt1:ret
  1108. TEKPNT  endp
  1109.  
  1110. ; Decode graphics x,y components. Returns carry set to say have all
  1111. ; components for a line, else carry clear. Understands 4014 lsb extensions.
  1112. ; Permits embedded escape sequences.
  1113. TEKXYC  proc    near
  1114.         cmp     al,CR                   ; Exit drawing on CR,LF,RS,US,FS,CAN
  1115.         je      tekghx                  ; e = yes, a cr
  1116.         cmp     al,LF                   ; these terminate line drawing cmds
  1117.         je      tekghx
  1118.         cmp     al,FS                   ; <FS>
  1119.         je      tekghx
  1120.         cmp     al,RS                   ; <RS>
  1121.         je      tekghx
  1122.         cmp     al,US                   ; <US>
  1123.         je      tekghx
  1124.         cmp     al,CAN                  ; and <CAN>
  1125.         je      tekghx                  ; BUT ignore other control chars
  1126.         cmp     al,20h                  ; Control char?
  1127.         jb      tekgh0                  ; b = yes, ignore it
  1128.         cmp     al,40h
  1129.         jb      tekgh2                  ; 20-3F are HIX or HIY
  1130.         cmp     al,60h                  ; 40-5F are LOX (causes beam movement)
  1131.         jb      tekgh4                  ; 60-7F are LOY
  1132.                                         ; Extract low-order 5 bits of Y coord
  1133.         mov     ah,tek_loy              ; Copy previous LOY to MSB (4014)
  1134.         mov     tek_lsb,ah
  1135.         and     al,1Fh                  ; LOY is 5 bits
  1136.         mov     tek_loy,al
  1137.         cmp     lastc,loy               ; 2nd LOY in a row?
  1138.         je      tekgh1                  ; Yes, then LSB is valid
  1139.         mov     tek_lsb,0               ; 1st one, clear LSB
  1140. tekgh1: mov     lastc,loy               ; LOY seen, expect HIX (instead of HIY)
  1141. tekgh0: clc                             ; c clear = not completed yet
  1142.         ret
  1143. tekghx: jmp     go2text
  1144.  
  1145.                         ; Extract high-order 5 bits (X or Y, depending on lastc)
  1146. tekgh2: and     ax,1Fh                  ; Just 5 bits
  1147.         mov     cl,5
  1148.         shl     ax,cl                   ; Shift over 5 bits
  1149.         cmp     lastc,loy               ; was last coordinate a low-y?
  1150.         je      tekgh3                  ; e = yes, parse hix
  1151.         mov     tek_hiy,ax              ; this byte has HIY
  1152.         mov     lastc,hiy
  1153.         clc
  1154.         ret
  1155. tekgh3: mov     tek_hix,ax              ; This byte has HIX
  1156.         mov     lastc,hix
  1157.         clc
  1158.         ret
  1159. tekgh4: and     al,1Fh                  ; Just 5 bits
  1160.         mov     tek_lox,al
  1161.         mov     lastc,lox
  1162.         mov     ax,tek_hix              ; Combine HIX*32
  1163.         or      al,tek_lox              ;  with LOX
  1164.         mov     bx,tek_hiy              ; Same for Y
  1165.         or      bl,tek_loy
  1166.         stc                             ; set c to say completed operation
  1167.         ret
  1168. TEKXYC  endp
  1169.  
  1170. TEKRLIN proc    near                    ; RS relative line drawing
  1171.         cmp     al,' '                  ; Pen up command?
  1172.         jne     tekrli1                 ; ne = no, try pen down
  1173.         mov     visible,0               ; do invisible movements
  1174.         jmp     short tekrli2           ; do the command
  1175. tekrli1:cmp     al,'P'                  ; pen down command?
  1176.         jne     tekrli3                 ; ne = no, return to text mode
  1177.         mov     visible,1               ; set visible moves
  1178.  
  1179. tekrli2:mov     ax,x_coord              ; PC x coordinate of pen
  1180.         mov     bx,y_coord              ;    y coordinate
  1181.         call    pctotek                 ; get current pen position in Tek coor
  1182.         mov     cl,0                    ; invisible, moveto
  1183.         call    tekdraw                 ; move that point, set oldx and oldy
  1184.         mov     ttstate,offset tekinc   ; next get incremental movement cmds
  1185.         ret
  1186.  
  1187. tekrli3:mov     visible,0               ; bad char, reset visibility
  1188.         push    prestate
  1189.         pop     ttstate                 ; restore previous state
  1190.         jmp     tektt5                  ; deal with the break char
  1191. TEKRLIN endp
  1192.                                         ; interpret RS inc plot command byte
  1193. TEKINC  proc    near                    ; get movement character and do cmd
  1194.         cmp     al,'A'                  ; move right?
  1195.         jne     tekinc1                 ; ne = no
  1196.         inc     oldx                    ; adjust beam position
  1197.         jmp     short tekinc9
  1198. tekinc1:cmp     al,'E'                  ; move right and up?
  1199.         jne     tekinc2                 ; ne = no
  1200.         inc     oldx
  1201.         inc     oldy
  1202.         jmp     short tekinc9
  1203. tekinc2:cmp     al,'D'                  ; move up?
  1204.         jne     tekinc3                 ; ne = no
  1205.         inc     oldy
  1206.         jmp     short tekinc9
  1207. tekinc3:cmp     al,'F'                  ; move left and up?
  1208.         jne     tekinc4                 ; ne = no
  1209.         dec     oldx
  1210.         inc     oldy
  1211.         jmp     short tekinc9
  1212. tekinc4:cmp     al,'B'                  ; move left?
  1213.         jne     tekinc5                 ; ne = no
  1214.         dec     oldx
  1215.         jmp     short tekinc9
  1216. tekinc5:cmp     al,'J'                  ; move left and down?
  1217.         jne     tekinc6                 ; ne = no
  1218.         dec     oldx
  1219.         dec     oldy
  1220.         jmp     short tekinc9
  1221. tekinc6:cmp     al,'H'                  ; move down?
  1222.         jne     tekinc7                 ; ne = no
  1223.         dec     oldy
  1224.         jmp     short tekinc9
  1225. tekinc7:cmp     al,'I'                  ; move right and down?
  1226.         jne     tekincb                 ; ne = no, bad command
  1227.         inc     oldx
  1228.         dec     oldy
  1229. tekinc9:cmp     oldx,0                  ; too far left?
  1230.         jge     tekinc10                ; ge = no
  1231.         mov     oldx,0                  ; else stop at the left margin
  1232. tekinc10:cmp    oldx,maxtekx-1          ; too far left?
  1233.         jle     tekinc11                ; le = no
  1234.         mov     oldx,maxtekx-1          ; else stop that the left margin
  1235. tekinc11:cmp    oldy,maxteky-1          ; above the top?
  1236.         jle     tekinc12                ; le = no
  1237.         mov     oldy,maxteky-1          ; else stop at the top
  1238. tekinc12:cmp    oldy,0                  ; below the bottom?
  1239.         jge     tekinc13                ; ge = no
  1240.         mov     oldy,0                  ; else stop at the bottom
  1241. tekinc13:mov    ax,oldx                 ; ax is vector x end point
  1242.         mov     bx,oldy                 ; bx is vector y end point
  1243.         mov     cl,visible
  1244.         call    tekdraw                 ; move/draw to that point
  1245.         ret
  1246. tekincb:push    prestate                ; bad character, exit inc plot mode
  1247.         pop     ttstate                 ; new state is previous state
  1248.         mov     visible,0
  1249.         jmp     tektt5                  ; reparse the bad char
  1250. TEKINC  endp
  1251.  
  1252.  
  1253. ; Routine to trigger the crosshairs, wait for a key to be struck, and send
  1254. ; the typed char (if printable ascii) plus four Tek encoded x,y position
  1255. ; coordinates and then a carriage return.
  1256. ; ax, cx, xcross, ycross operate in PC coordinates.
  1257.  
  1258. CROSHAIR PROC NEAR
  1259.         push    linepat                 ; save line drawing pattern
  1260.         mov     linepat,0ffffh          ; reset line type to solid
  1261.  
  1262.         mov     ax,xmax                 ; right margin minus 7 dots
  1263.         add     ax,7
  1264.         mov     temp,ax                 ; right margin dot
  1265. crosha1:call    crosdraw                ; draw the cross-hairs
  1266.         call    iseof                   ; is stdin at EOF?
  1267.         jc      crosha2                 ; c = yes, exit this mode now
  1268.         mov     ah,coninq               ; DOS, quiet read char
  1269.         int     dos
  1270.         push    ax                      ; save char for later
  1271.         call    crosdraw                ; erase cross hairs
  1272.         pop     ax
  1273.         or      al,al                   ; ascii or scan code returned
  1274.         jnz     arrow5                  ; nz = ascii char returned
  1275.  
  1276.         call    iseof                   ; is stdin at EOF?
  1277.         jc      crosha2                 ; c = yes, exit this mode now
  1278.         mov     ah,coninq               ; read scan code
  1279.         int     dos
  1280.         cmp     al,0                    ; Control-Break?
  1281.         jne     crosha3                 ; ne = no, something else
  1282. crosha2:pop     linepat                 ; restore line pattern
  1283.         ret                             ; exit crosshairs mode
  1284.  
  1285. crosha3:cmp     al,homscn               ; is it 'home'?
  1286.         jne     arrow1                  ; ne = no, try other keys
  1287.         mov     ax,temp                 ; right margin
  1288.         shr     ax,1                    ; central position
  1289.         mov     xcross,ax               ; save PC coord for crosshair
  1290.         mov     ax,ybot                 ; last scan line
  1291.         shr     ax,1
  1292.         mov     ycross,ax               ; this is the center of the screen
  1293.         jmp     crosha1                 ; home the crosshairs
  1294.  
  1295. arrow1: cmp     al,lftarr               ; left arrow?
  1296.         jne     arrow2                  ; ne = no
  1297.         mov     cx,-1                   ; left shift
  1298.         jmp     short xkeys
  1299. arrow2: cmp     al,rgtarr               ; right arrow?
  1300.         jne     arrow3                  ; ne = no
  1301.         mov     cx,1                    ; right shift
  1302.         jmp     short xkeys
  1303. arrow3: cmp     al,uparr                ; up arrow?
  1304.         jne     arrow4                  ; ne = no
  1305.         mov     cx,-1                   ; up shift
  1306.         jmp     short vertkey
  1307. arrow4: cmp     al,dnarr                ; down arrow?
  1308.         jne     badkey                  ; ne = no, ignore it
  1309.         mov     cx,1                    ; down shift
  1310.         jmp     short vertkey
  1311.  
  1312. badkey: call    beep                    ; tell user we don't understand
  1313.         jmp     crosha1                 ; keep going
  1314.  
  1315.                                         ; Shifted keys yield ascii keycodes
  1316. arrow5: cmp     al,'C' and 1fh          ; Control-C?
  1317.         je      crosha2                 ; e = yes, exit crosshairs mode now
  1318.         cmp     al,shlftarr             ; shifted left arrow?
  1319.         jne     arrow6                  ; ne = no
  1320.         mov     cx,-10                  ; big left shift
  1321.         jmp     short xkeys
  1322. arrow6: cmp     al,shrgtarr             ; shifted right arrow?
  1323.         jne     arrow7                  ; ne = no
  1324.         mov     cx,10                   ; big right shift
  1325.         jmp     short xkeys
  1326. arrow7: cmp     al,shuparr              ; shifted up arrow?
  1327.         jne     arrow8                  ; ne = no
  1328.         mov     cx,-10                  ; big up shift
  1329.         jmp     short vertkey
  1330. arrow8: cmp     al,shdnarr              ; shifted down arrow?
  1331.         jne     charkey                 ; ne = no, send this key as is
  1332.         mov     cx,10                   ; big down shift
  1333.         jmp     short vertkey
  1334.  
  1335. xkeys:  add     cx,xcross               ; add increment
  1336.         jns     noxc                    ; gone too far negative?
  1337.         mov     cx,0                    ; yes - then make it 0
  1338. noxc:   cmp     cx,temp                 ; too far right?
  1339.         jb      xdraw9                  ; b = no
  1340.         mov     cx,temp                 ; yes - then make it the right
  1341. xdraw9: mov     xcross,cx               ; new x value for cross hairs
  1342.         jmp     crosha1                 ; and redraw
  1343.  
  1344. vertkey:add     cx,ycross               ; adjust cx
  1345.         jns     noyc                    ; gone negative?
  1346.         mov     cx,0                    ; yes then make 0
  1347. noyc:   cmp     cx,ybot                 ; too high?
  1348.         jb      yok
  1349.         mov     cx,ybot                 ; make it maximum
  1350. yok:    mov     ycross,cx               ; save new y crosshair
  1351.         jmp     crosha1                 ; and redraw
  1352.  
  1353. charkey:call    clrbuf                  ; purge received data to date
  1354.         call    outmodem                ; send the break character
  1355.         mov     ax,xcross               ; set beam to xcross,ycross
  1356.         mov     bx,ycross               ; must convert to Tek coordinates
  1357.         call    pctotek                 ; scale from PC screen coord to Tek
  1358.         push    ax                      ; save around drawing
  1359.         push    bx
  1360.         mov     cx,0                    ; just a move
  1361.         call    tekdraw                 ; moveto ax,bx in Tek coord
  1362.         pop     bx                      ; recover Tek y
  1363.         pop     ax                      ; recover Tek x
  1364.         call    sendpos                 ; send position report to host
  1365.         pop     linepat                 ; recover current line drawing pattern
  1366.         mov     ttstate,offset tektxt   ; Go to TEKTXT next time
  1367.         mov     lastc,0                 ; clear last drawing coordinate flag
  1368.         or      status,txtmode          ; set text mode in status byte
  1369.         ret
  1370. CROSHAIR ENDP
  1371.  
  1372. ; CROSDRAW draws cross-hairs by XORing cross with picture.
  1373. ; xcross and ycross are in PC coordinates.
  1374. CROSDRAW PROC   NEAR
  1375.         mov     si,xcross               ; move to (xcross, ycross-10)
  1376.         mov     di,ycross
  1377.         sub     di,10                   ; half the size of the cross
  1378.         jns     crosd1                  ; no sign bit means ok
  1379.         mov     di,0                    ; else limit to start of screen
  1380. crosd1: mov     ax,si                   ; next, draw to (xcross, ycross+10)
  1381.         mov     bx,ycross               ; make bottom stroke
  1382.         add     bx,10
  1383.         cmp     bx,ybot                 ; too large?
  1384.         jbe     crosd2                  ; be = no
  1385.         mov     bx,ybot                 ; vertical line to (xcross,ybot)
  1386. crosd2: mov     cx,0ffh                 ; invert pixels
  1387.         call    line                    ; and draw vertical
  1388.         sub     si,12                   ; move to (xcross-12, ycross)
  1389.         jns     crosd3                  ; no sign means ok
  1390.         mov     si,0                    ; else limit to start of line
  1391. crosd3: mov     di,ycross
  1392.         mov     bx,di
  1393.         mov     ax,xcross               ; draw to (xcross+12, ycross)
  1394.         add     ax,12
  1395.         cmp     ax,temp                 ; temp is right margin, too large?
  1396.         jbe     crosd4                  ; be = no, ok
  1397.         mov     ax,temp                 ; max x value
  1398. crosd4: mov     cx,0ffh                 ; set XOR code
  1399.         call    line                    ; draw to (xcross+12, ycross)
  1400.         ret
  1401. CROSDRAW ENDP
  1402.  
  1403. ; SENDPOS sends position of cross-hairs to the host.
  1404. ; ax has Tek X and bx has Tek Y coord of center of crosshair
  1405. SENDPOS PROC NEAR
  1406.         push    bx                      ; preserve register
  1407.         call    sendxy                  ; send x coord
  1408.         pop     ax
  1409.         call    sendxy                  ; send y coord
  1410.         mov     al,cr                   ; follow up with cr
  1411.         call    outmodem
  1412.         ret
  1413. SENDPOS ENDP
  1414.  
  1415. ; SENDXY sends value of ax as Tek encoded bytes
  1416. ; ax is in Tek coordinates
  1417. SENDXY  PROC    NEAR
  1418.         shl     ax,1
  1419.         shl     ax,1                    ; move all but lower 5 bits to ah
  1420.         shl     ax,1
  1421.         shr     al,1
  1422.         shr     al,1                    ; move low five bits to low 5 bits
  1423.         shr     al,1
  1424.         or      ah,20h                  ; make it a printing char as per TEK
  1425.         xchg    al,ah                   ; send high 5 bits first
  1426.         call    outmodem
  1427.         xchg    al,ah                   ; then low five bits
  1428.         or      al,20h
  1429.         call    outmodem
  1430.         xchg    ah,al                   ; al is first sent byte
  1431.         ret
  1432. SENDXY  ENDP
  1433.  
  1434.  
  1435. SENDID  PROC NEAR                       ; Pretend VT100 with graphics option
  1436.         mov     bx,IDSEQ                ; Get addr of string
  1437. sndid1: mov     al,[bx]                 ; Get char from sequence
  1438.         cmp     al,0                    ; End of sequence?
  1439.         jz      sndid0                  ; Yes, return
  1440.         call    OUTMODEM                ; Send it out the port
  1441.         inc     bx
  1442.         jmp     sndid1
  1443. sndid0: ret
  1444. SENDID  ENDP
  1445.  
  1446. ; SENDSTAT - send status and cursor position to host
  1447.  
  1448. SENDSTAT PROC NEAR
  1449.         mov     al,STATUS               ; get tek status
  1450.         or      al,20h                  ; make it printable
  1451.         call    OUTMODEM                ; and send it
  1452.         mov     ax,oldx                 ; now send x coordinate (oldx is Tek)
  1453.         call    SENDXY
  1454.         mov     ax,oldy                 ; and y coordinate (oldy is Tek coord)
  1455.         call    SENDXY
  1456.         mov     al,cr                   ; end with a cr
  1457.         call    OUTMODEM
  1458.         ret
  1459. SENDSTAT ENDP
  1460.  
  1461. ; routine to send al to the modem port
  1462.  
  1463. OUTMODEM PROC   NEAR
  1464.         push    ax
  1465.         mov     ah,al
  1466.         call    outchr                  ; outchr reads from ah
  1467.          nop                            ; ignore errors
  1468.          nop
  1469.          nop
  1470.         pop     ax
  1471.         ret
  1472. OUTMODEM ENDP
  1473.  
  1474. ; Convert X and Y from PC coordinates to Tek coordinates. AX = X, BX = Y
  1475. ; for both input and output.
  1476. pctotek proc    near
  1477.         mul     xdiv                    ; scale from PC screen coord to Tek
  1478.         div     xmult
  1479.         xchg    bx,ax                   ; save Tek x coord in bx
  1480.         neg     ax                      ; y axis. Turn upside down for Tek
  1481.         add     ax,ybot
  1482.         mul     ydiv                    ; scale y from PC screen coord to Tek
  1483.         div     ymult
  1484.         xchg    ax,bx                   ; ax has X, bx has Y in Tek coords
  1485.         ret
  1486. pctotek endp
  1487.  
  1488. ; Routine to output character in AL to the screen.
  1489.  
  1490. OUTSCRN PROC NEAR                       ; Output one character to the screen
  1491.         cmp     bypass,0                ; GIN mode bypass off?
  1492.         je      outscp                  ; e = yes
  1493.         ret                             ;  else ignore characters
  1494. outscp:                                 ; Set Translation Input filter
  1495.         cmp     rxtable+256,0           ; translation turned off?
  1496.         je      outsct                  ; e = yes, no translation
  1497.         push    bx
  1498.         mov     bx,offset rxtable       ; address of translate table
  1499.         xlatb                           ; new char is in al
  1500.         and     al,7fh                  ; retain only lower seven bits
  1501.         pop     bx
  1502. outsct: mov     si,ybot                 ; get last scan line
  1503.         inc     si                      ; number of scan lines
  1504.         sub     si,y_coord              ; minus where char bottom needs to go
  1505.         jnc     outscc                  ; nc = enough space for char
  1506.                                         ; else give "More >" message
  1507.         push    ax                      ; save current char
  1508.         push    cx
  1509.         mov     cx,mormsglen            ; characters in More message
  1510.         mov     ax,cx
  1511.         shl     ax,1
  1512.         shl     ax,1
  1513.         shl     ax,1                    ; times 8 bits/character
  1514.         neg     ax                      ; (note: leave last char cell empty)
  1515.         add     ax,xmax                 ; right justify
  1516.         mov     x_coord,ax              ; set starting x dot
  1517.         mov     ax,ybot
  1518.         mov     y_coord,ax              ; set starting y line
  1519.         mov     ccode,1                 ; write in foreground colors
  1520.         push    cx
  1521.         mov     al,DEL                  ; fill all pixels
  1522. outscm1:call    putc                    ; write
  1523.         loop    outscm1
  1524.         pop     cx
  1525.         push    cx
  1526.         mov     al,BS                   ; backup to overwrite with More text
  1527. outscm2:call    putc
  1528.         loop    outscm2
  1529.         pop     cx
  1530.         mov     ccode,0                 ; main text in background colors
  1531.         mov     si,offset moremsg       ; give More message
  1532. outsclf:cld
  1533.         lodsb                           ; read a byte from string
  1534.         call    putc                    ; display the string
  1535.         loop    outsclf                 ; repeat for all string chars
  1536.         pop     cx
  1537.         mov     ccode,1                 ; restore normal foreground coloring
  1538.         call    iseof                   ; EOF on redirected stdin?
  1539.         jc      outscl3                 ; c = yes, proceed anyway
  1540.         mov     ah,coninq               ; read keyboad via DOS
  1541.         int     dos                     ; wait for keystroke
  1542.         or      al,al                   ; scan code being returned?
  1543.         jne     outscl3                 ; ne = no
  1544.         mov     ah,coninq               ; clear away scan code too
  1545.         int     dos
  1546. outscl3:call    tekcls                  ; clear the screen
  1547.         pop     ax                      ; recover current character
  1548.         cmp     al,lf                   ; just a line feed?
  1549.         jne     outscc                  ; ne = no, display it
  1550.         ret                             ;  else ignore the line feed
  1551.  
  1552. outscc: push    ax
  1553.         mov     ax,xmax
  1554.         cmp     x_coord,ax              ; beyond right margin?
  1555.         jbe     outsc3                  ; be = no
  1556.         mov     al,cr                   ; else simulate cr/lf
  1557.         call    putc                    ; before displaying current char
  1558.         mov     al,lf
  1559.         call    putc
  1560. outsc3: pop     ax
  1561.         call    putc                    ; routine to draw characters
  1562.         ret
  1563. OUTSCRN ENDP
  1564.  
  1565.  
  1566. ; TEKCLS routine to clear the screen.
  1567. ; Entry point tekcls1 clears screen without resetting current point.
  1568. TEKCLS  PROC    NEAR
  1569.         cmp     tekflg,0                ; Tek sub mode active yet?
  1570.         jne     tekcls0                 ; ne = yes
  1571.         ret                             ; else ignore this call
  1572. tekcls0:mov     x_coord,0               ; starting text coordinates
  1573.         mov     y_coord,8
  1574.         mov     oldx,0                  ; assumed cursor starting location
  1575.         mov     oldy,maxteky            ;  top right corner (Tek coord)
  1576.         mov     scalex,0                ; clear last plotted point (PC coord)
  1577.         mov     scaley,0
  1578.         mov     lastc,0                 ; last parsed x,y coordinate
  1579.         mov     visible,0               ; make lines invisible
  1580.         mov     linepat,0ffffh          ; reset line pattern to solid
  1581.         mov     ccode,1                 ; reset to ordinary writing
  1582.         mov     bypass,0                ; clear bypass condition
  1583.         mov     ttstate,offset tektxt   ; do displayable text
  1584.         push    ax
  1585.         mov     ax,xmax                 ; right margin minus 7 dots
  1586.         add     ax,7                    ; right most dot
  1587.         shr     ax,1                    ; central position
  1588.         mov     xcross,ax               ; save PC coord for crosshair
  1589.         mov     ax,ybot                 ; last scan line
  1590.         shr     ax,1
  1591.         mov     ycross,ax               ; this is the center of the screen
  1592.         pop     ax
  1593.  
  1594. tekcls1:push    ax                      ; save registers
  1595.         push    cx
  1596.         cmp     graph_mode,hercules     ; Hercules?
  1597.         jne     tekcls2                 ; ne = no
  1598.         call    hgraf                   ; set Hercules board to Graphics mode
  1599.         jmp     tekcls7
  1600.  
  1601. tekcls2:mov     di,0                    ; point to start of screen, di=row
  1602.         call    psetup                  ; setup graphics routine and es:di
  1603.         mov     cx,4000h                ; CGA, 200 lines times 80 bytes worth
  1604.         cmp     graph_mode,cga          ; cga?
  1605.         je      tekcls3                 ; e = yes
  1606.         mov     cx,8000h                ; Olivetti, 400 lines times 80 bytes
  1607.         cmp     graph_mode,olivetti     ; AT&T-Olivetti?
  1608.         je      tekcls3                 ; e = yes
  1609.         cmp     graph_mode,toshiba      ; Toshiba?
  1610.         je      tekcls3                 ; e = yes
  1611.         cmp     graph_mode,vaxmate      ; VAXmate?
  1612.         jne     tekcls4                 ; ne = no
  1613. tekcls3:cld                             ; clear screen directly of text stuff
  1614.         mov     al,0                    ; color is black
  1615.         rep     stosb                   ; clear the bytes
  1616.         jmp     short tekcls7
  1617.  
  1618. tekcls4:cmp     graph_mode,ega          ; EGA?
  1619.         je      tekcls5                 ; e = yes
  1620.         cmp     graph_mode,monoega      ; EGA with mono display?
  1621.         je      tekcls5                 ; e = yes
  1622.         cmp     graph_mode,colorega     ; EGA with medium resolution monitor?
  1623.         je      tekcls5                 ; e = yes
  1624.         jmp     short tekcls6           ; else use Bios
  1625.  
  1626. tekcls5:                                ; EGA clear screen quickly
  1627.         mov     ax,0ff08h               ; set all 8 bits to be changed
  1628.         call    ega_gc                  ; set bit mask register accordingly
  1629.         mov     cx,ybot                 ; last scan line
  1630.         inc     cx                      ; number of scan lines
  1631.         mov     ax,80                   ; bytes per scan line
  1632.         mul     cx
  1633.         mov     cx,ax                   ; cx = number of bytes to clear
  1634.         mov     al,gbcol                ; select background colour
  1635.         cld
  1636.         rep     stosb                   ; write backgound color
  1637.         jmp     short tekcls7
  1638.  
  1639. tekcls6:push    es                      ; clear screen by scrolling up
  1640.         call    cmblnk                  ; clear screen, for Environments
  1641.         pop     es
  1642.  
  1643. tekcls7:mov     si,0                    ; starting x  (in case screen is
  1644.         mov     di,0                    ; starting y    cleared by user)
  1645.         pop     cx
  1646.         pop     ax
  1647.         ret
  1648. TEKCLS  ENDP
  1649.  
  1650. ; Routine to draw a line on the screen, using TEKTRONIX coordinates.
  1651. ; X coordinate in AX, 0=left edge of screen, 1023=right edge of screen.
  1652. ; Y coordinate in BX, 0=bottom of screen, 779=top of screen.
  1653. ; CL=0 - invisible move, CL=1 - draw a line, CL=0FFh - invert pixels on line
  1654.  
  1655. TEKDRAW PROC NEAR
  1656.         mov     si,scalex               ; get old x already scaled
  1657.         mov     di,scaley               ; get old y already scaled
  1658.         call    scale                   ; scale new end point to PC coords
  1659.         cmp     cl,0                    ; invisible drawing?
  1660.         je      moveto                  ; z = just move, skip draw part
  1661.         call    LINE                    ; draw the line
  1662. moveto: mov     x_coord,ax              ; update text coordinates to match
  1663.         mov     y_coord,bx              ;  last drawn point
  1664.         ret
  1665. TEKDRAW ENDP
  1666.  
  1667. ; Scale TEKTRONIX coordinates to the currently defined screen coordinates
  1668. ; AX holds X axis, BX holds Y axis. Both are changed from Tektronix coord
  1669. ; to PC coordinates by this procedure.
  1670. SCALE   PROC    NEAR
  1671.         push    dx
  1672.         push    si
  1673.         mov     oldx,ax                 ; save current Tek x for next draw
  1674.         mov     oldy,bx                 ; save current Tek y for next draw
  1675.         mul     xmult                   ; scale x-coord
  1676.         mov     si,xdiv                 ; get the divisor
  1677.         shr     si,1                    ; halve it
  1678.         add     ax,si                   ; add in - to round to nearest integer
  1679.         adc     dx,0
  1680.         div     xdiv
  1681.         push    ax
  1682.         mov     ax,bx
  1683.         mul     ymult                   ; scale y-coord
  1684.         mov     si,ydiv                 ; get divisor
  1685.         shr     si,1                    ; halve it
  1686.         add     ax,si                   ; add in - to round to nearest integer
  1687.         adc     dx,0
  1688.         div     ydiv
  1689.         mov     bx,ybot
  1690.         sub     bx,ax                   ; Put new Y in right reg
  1691.         jns     scale3                  ; ns = not too far
  1692.         mov     bx,0
  1693. scale3: pop     ax                      ; Put new X in right reg
  1694.         mov     scalex,ax               ; save scaled values
  1695.         mov     scaley,bx
  1696.         pop     si
  1697.         pop     dx
  1698.         ret
  1699. SCALE   ENDP
  1700.  
  1701. ; LINE  Subroutine to plot a line with endpoints in AX,BX and SI,DI.
  1702. ;       fast line drawing routine for the IBM PC
  1703. ;
  1704. ; Registers at CALL
  1705. ; -----------------
  1706. ; SI=Start X coord, all in PC coordinates
  1707. ; DI=Start Y coord
  1708. ; AX=End X coord
  1709. ; BX=End Y coord
  1710. ; CL=Color code: 1=draw foreground, 0=draw background, 0ffh=invert
  1711. ; BP= line drawing pattern (is changed here by rotation)
  1712. ; registers are all unchanged
  1713.  
  1714. LINE    PROC    NEAR
  1715.         push    ax
  1716.         push    bx
  1717.         push    cx
  1718.         push    dx
  1719.         push    si
  1720.         push    di
  1721.         push    es
  1722.         mov     bp,linepat              ; store active line pattern word in BP
  1723.         mov     ccode,cl        ; save color code in ccode for use by plot()
  1724.                         ; first get coord to achieve increasing x; deltax >= 0
  1725.         sub     ax,si                   ; deltax = x2 - x1
  1726.         jge     line1                   ; ge = going to the right, as desired
  1727.         neg     ax                      ; make deltax non-negative
  1728.         sub     si,ax                   ; swap the x coordinates
  1729.         xchg    bx,di                   ; swap the y coordinates too
  1730.                                 ; second, compute deltay. ax = deltax, si = x1
  1731. line1:  sub     bx,di                   ; deltay = y2 - y1
  1732.         call    psetup                  ; setup display adapter for plotting
  1733.                                         ;  and setup es:di to screen memory
  1734.   ; Choose algorithm based on |deltay| < |deltax| (use shallow) else steep.
  1735.   ; We arrange matters such that both deltas are non-negative.
  1736.         cmp     bx,0                    ; deltay
  1737.         jge     line2                   ; ge = non-negative
  1738.         neg     linelen
  1739.         neg     bx                      ; make non-negative
  1740. line2:  cmp     bx,ax                   ; |deltay| versus |deltax|
  1741.         jbe     shallow                 ; be = do shallow algorithm
  1742.         jmp     steep                   ; else do steep algorithm
  1743.  
  1744.         ; shallow algorithm, move along x, di=y1, bx=deltay, si=x1, ax=deltax
  1745. shallow:add     bx,bx                   ; bx = 2*deltay
  1746.         mov     cx,ax                   ; cx = number of steps (deltax here)
  1747.         inc     cx                      ; loop dec's cx before testing
  1748.         mov     dx,bx                   ; dx holds error
  1749.         sub     dx,ax                   ; error = 2*deltay - deltax
  1750.         add     ax,ax                   ; ax = 2*|deltax|
  1751. shal1:  call    plotptr                 ; Plot(x,y)
  1752.         cmp     dx,0
  1753.         jle     shal2                   ; le =   error <= 0
  1754.         call    pincy                   ; increment y by one scan line
  1755.         sub     dx,ax                   ; error = error - 2*deltax
  1756. shal2:  add     dx,bx                   ; error = error + 2*deltay
  1757.         inc     si                      ; x = next dot right
  1758.         loop    shal1
  1759. shal3:  jmp     short plotex
  1760.  
  1761.         ; steep algorithm, move along y, di=y1, bx=deltay, si=x1, ax=deltax
  1762. steep:  add     ax,ax                   ; ax = 2*deltax
  1763.         mov     dx,ax                   ; dx holds error
  1764.         sub     dx,bx                   ; error = 2*deltax(bx) - deltay (bx)
  1765.         mov     cx,bx                   ; cx = number of steps (deltay here)
  1766.         inc     cx                      ; loop dec's cx before testing
  1767.         add     bx,bx                   ; bx = 2*|deltay|
  1768. stee1:  call    plotptr                 ; Plot(x,y) x = ax, y = di
  1769.         cmp     dx,0
  1770.         jle     stee2                   ; le  error <= 0
  1771.         inc     si                      ; x = next dot right
  1772.         sub     dx,bx                   ; error = error - 2*deltay
  1773. stee2:  add     dx,ax                   ; error = error + 2*deltax
  1774.         call    pincy                   ; increment y
  1775.         loop    stee1
  1776. stee3:;;;jmp    plotex
  1777.  
  1778. plotex: mov     ccode,1                 ; reset to do foreground coloring
  1779.         pop     es
  1780.         pop     di
  1781.         pop     si
  1782.         pop     dx                      ; restore the world
  1783.         pop     cx
  1784.         pop     bx
  1785.         pop     ax
  1786.         ret
  1787. LINE    ENDP
  1788.  
  1789. ;;;;;;; EGA plot support routines
  1790. psetupe proc    near                    ; EGA setup for plotting
  1791.         push    ax
  1792.         mov     linelen,80              ; for y going down screen by pincy
  1793.         mov     ax,segscn               ; set es to screen memory segment
  1794.         mov     es,ax
  1795.         mov     ax,0205h                ; mode: write mode 2
  1796.         call    ega_gc
  1797.         mov     ax,0003h                ; assume writing bits directly
  1798.         cmp     ccode,0ffh              ; inverting bits?
  1799.         jne     psete2                  ; ne = no
  1800.         mov     ax,1803h                ; then say XOR the bits
  1801. psete2: call    ega_gc                  ; set controller
  1802.         mov     ax,80                   ; compute starting point in regen buff
  1803.         mul     di
  1804.         mov     di,ax                   ; di = di * 80
  1805.         pop     ax
  1806.         ret
  1807. psetupe endp
  1808.  
  1809. pincye  proc    near                    ; EGA inc y
  1810.         add     di,linelen              ; includes sign of deltay
  1811.         ret
  1812. pincye  endp
  1813.  
  1814. pltega  proc    near            ; EGA plot(x,y). x is in si, y is in di
  1815.         rol     bp,1                    ; rotate line pattern
  1816.         jnc     pltega1                 ; nc = no bit to be plotted
  1817.         push    bx
  1818.         push    si
  1819.         push    di
  1820.         mov     bx,si                   ; want si/8 for bytes along line
  1821.         shr     si,1
  1822.         shr     si,1
  1823.         shr     si,1
  1824.         add     di,si                   ; starting point in regen buffer
  1825.         and     bx,0007h                ; leave lower 3 bits for bit in byte
  1826.         mov     bh,masktab[bx]          ; 0-7 into bit mask in byte, x pos
  1827.         mov     bl,ccode                ; get line type code
  1828.         call    ega_plt
  1829.         pop     di
  1830.         pop     si
  1831.         pop     bx
  1832. pltega1:ret
  1833. pltega  endp
  1834.  
  1835. ;;;;;;;; CGA plot support routines
  1836. ; The CGA graphics memory mapping in mode 6 (640 by 200) is 8 dots per byte,
  1837. ; left most dot in the high bit, 80 bytes per scan line, scan line segments
  1838. ; alternating between 0b800h (even lines 0, 2, ...) and 0ba00h (odd lines).
  1839. psetupc proc    near                    ; CGA setup for plotting
  1840.         push    ax
  1841.         push    cx
  1842.         mov     linelen,80              ; 80 bytes per scan line
  1843.         mov     cx,segscn
  1844.         mov     es,cx
  1845.         mov     cx,di                   ; save copy of di, start y line
  1846.                                         ; compute starting point in regen buff
  1847.         shr     di,1                    ; half the lines in each bank
  1848.         mov     ax,80                   ; 80 bytes per line
  1849.         mul     di
  1850.         mov     di,ax                   ; di = di * 80 / 2
  1851.         test    cx,1                    ; even or odd line
  1852.         jz      psetc1                  ; z = even
  1853.         add     di,2000h                ; offset to odd bank (seg 0ba00h)
  1854. psetc1: and     di,3fffh
  1855.         pop     cx
  1856.         pop     ax
  1857.         ret
  1858. psetupc endp
  1859.  
  1860. pincyc  proc    near                    ; CGA inc y
  1861.         cmp     linelen,0               ; increasing or decreasing y?
  1862.         jl      pinyc2                  ; l = decreasing
  1863.         cmp     di,2000h                ; in upper bank now?
  1864.         jb      pinyc1                  ; b = no, in lower bank
  1865.         add     di,linelen              ; add a line
  1866. pinyc1: add     di,2000h                ; switch banks
  1867.         and     di,3fffh                ; roll over address
  1868.         ret
  1869. pinyc2: cmp     di,2000h                ; in upper bank now?
  1870.         jae     pinyc4                  ; ae = yes
  1871.         add     di,linelen              ; subtract a line
  1872. pinyc4: add     di,2000h                ; switch banks
  1873.         and     di,3fffh                ; roll over address
  1874.         ret
  1875. pincyc  endp
  1876.  
  1877. pltcga  proc    near            ; CGA plot(x,y). x is in si, y is in di
  1878.         push    bx              ; used for HGA plot also.
  1879.         push    si
  1880.         push    di
  1881.         rol     bp,1                    ; rotate line pattern
  1882.         jnc     pltcg3                  ; nc = no bit to be plotted
  1883.         mov     bx,si                   ; want si/8 for bytes along line
  1884.         shr     si,1
  1885.         shr     si,1
  1886.         shr     si,1
  1887.         add     di,si                   ; starting point in regen buffer
  1888.         and     bx,0007h                ; leave lower 3 bits for bit in byte
  1889.                                         ; di = offset in regen buffer
  1890.         mov     bh,masktab[bx]          ; 0-7 into bit mask in byte. x position
  1891.         mov     bl,ccode                ; get line type code
  1892.         cmp     bl,1                    ; draw the bit?
  1893.         jne     pltcg1                  ; ne = no
  1894.         or      es:[di],bh              ; drawn
  1895.         jmp     short pltcg3
  1896. pltcg1: cmp     bl,0                    ; draw in background (erase)?
  1897.         jne     pltcg2                  ; ne = no
  1898.         not     bh
  1899.         and     es:[di],bh              ; erase the dots
  1900.         jmp     short pltcg3
  1901. pltcg2: xor     es:[di],bh              ; xor in this color
  1902. pltcg3: pop     di
  1903.         pop     si
  1904.         pop     bx
  1905.         ret
  1906. pltcga  endp
  1907.  
  1908. ;;;;;;; HGA plot support routines
  1909. ; The HGA graphics memory mapping in mode 255 (720 by 348) is 8 dots per byte,
  1910. ; left most dot in the high bit, 90 bytes per scan line, scan line segments
  1911. ; sequence as 0b000h, 0b200h, 0b400h, 0b800h for lines 0-3 and repeat 90 bytes
  1912. ; higher for the rest.
  1913. psetuph proc    near                    ; HGA setup for plotting
  1914.         push    ax
  1915.         push    cx
  1916.         mov     linelen,90              ; for y going down screen by incy
  1917.         mov     ax,segscn               ; base segment of display memory
  1918.         mov     es,ax
  1919.         mov     cx,di                   ; save copy of di, start y line
  1920.                                         ; compute starting point in regen buff
  1921.         shr     di,1                    ; quarter the lines in each bank
  1922.         shr     di,1
  1923.         mov     ax,90
  1924.         mul     di
  1925.         mov     di,ax                   ; di = di * 90 / 4
  1926.         and     cx,3                    ; compute bank from 2 lsb of line num
  1927.         jcxz    pseth2                  ; z means it is in bank 0 (0b000h)
  1928. pseth1: add     di,2000h                ; add offset for each bank
  1929.         loop    pseth1                  ; do cx times
  1930. pseth2: pop     cx
  1931.         pop     ax
  1932.         ret
  1933. psetuph endp
  1934.  
  1935. pincyh  proc    near                    ; HGA inc y, step offset of line
  1936.         cmp     linelen,0               ; increasing y?
  1937.         jg      pinyh2                  ; g = yes
  1938.         cmp     di,2000h                ; in lowest for four banks?
  1939.         ja      pinyh1                  ; a = no
  1940.         add     di,linelen              ; yes, add a line
  1941. pinyh1: add     di,6000h                ; move back by adding a lot
  1942.         and     di,7fffh                ; roll over address
  1943.         ret
  1944. pinyh2: cmp     di,6000h                ; in top most bank?
  1945.         jb      pinyh4                  ; b = no
  1946.         add     di,linelen              ; yes, first add a line
  1947. pinyh4: add     di,2000h                ; switch to next bank
  1948.         and     di,7fffh                ; roll over address
  1949.         ret
  1950. pincyh  endp
  1951.  
  1952. ;;;;;;; AT&T-Olivetti, Toshiba, VAXmate Graphics Adapter plot support routines
  1953. ; The graphics memory mapping in 640 by 400 mode is 8 dots per byte,
  1954. ; left most dot in the high bit, 80 bytes per scan line, scan line segments
  1955. ; sequence as 0b800h, 0ba00h, 0bc00h, 0be00h for lines 0-3 and repeat 80 bytes
  1956. ; higher for the rest. Use Hercules line incrementing (inc y) and CGA dot
  1957. ; writing. This is a monographic display.
  1958. psetupo proc    near                    ; setup for plotting
  1959.         push    ax
  1960.         push    cx
  1961.         mov     linelen,80              ; for y going down screen by incy
  1962.         mov     ax,segscn               ; base segment of display memory
  1963.         mov     es,ax
  1964.         mov     cx,di                   ; save copy of di, start y line
  1965.                                         ; compute starting point in regen buff
  1966.         shr     di,1                    ; quarter the lines in each bank
  1967.         shr     di,1
  1968.         mov     ax,80
  1969.         mul     di
  1970.         mov     di,ax                   ; di = di * 80 / 4
  1971.         and     cx,3                    ; compute bank from 2 lsb of line num
  1972.         jcxz    pseto2                  ; z means it is in bank 0 (0b800h)
  1973. pseto1: add     di,2000h                ; add offset for each bank
  1974.         loop    pseto1                  ; do cx times
  1975. pseto2: pop     cx
  1976.         pop     ax
  1977.         ret
  1978. psetupo endp
  1979.  
  1980. ;;;;;;;; Monochrome, simulate dots with text char
  1981. psetupm proc    near
  1982.         mov     linelen,1               ; 80 characters but one line
  1983.         ret
  1984. psetupm endp
  1985.  
  1986. pltmon  proc    near                    ; Monochrome dot plot
  1987.         mov     x_coord,si              ; put dot at row=di, col=si, PC Coord
  1988.         mov     y_coord,di
  1989.         push    ax
  1990.         mov     al,'+'                  ; our dot character
  1991.         call    mputc                   ; display text char
  1992.         pop     ax
  1993.         ret
  1994. pltmon  endp
  1995.  
  1996. pincym  proc    near                    ; Monochrome inc y
  1997.         add     di,linelen              ; includes sign
  1998.         ret
  1999. pincym  endp
  2000.  
  2001. ; GPUTC - a routine to send text characters from font to true graphics boards
  2002. ; such as EGA, Hercules or CGA. Char is in al. Drawing routine ptr is gcplot.
  2003.  
  2004. gputc   proc    near
  2005.         cmp     al,' '                  ; control character?
  2006.         jae     gputc1                  ; ae = no, display the char
  2007.         jmp     putctrl                 ; else handle controls at putctrl
  2008. gputc1: push    ax                      ; first save some registers
  2009.         push    bx
  2010.         push    cx
  2011.         push    es
  2012.         push    di
  2013.         mov     bl,al                   ; now BL has char to be displayed
  2014.         and     bl,7fh                  ; no high bits allowed here
  2015.                                         ; set board mode
  2016.         mov     di,y_coord              ; get current y coord (char bottom)
  2017.         sub     di,8                    ; start 8 lines higher
  2018.         jnc     gputc2                  ; nc = ok
  2019.         mov     di,0                    ; move up to first line
  2020.         mov     y_coord,8               ; and reset scan line indicator
  2021. gputc2: call    psetup          ; enter with di=line number, sets es:di to
  2022.                                 ; start of line in display buf and
  2023.                                 ; sets byte-wide plot mode
  2024.         mov     ax,x_coord              ; compute regen buffer byte
  2025.         shr     ax,1                    ; want x_coord/8 for bytes along line
  2026.         shr     ax,1
  2027.         shr     ax,1
  2028.         add     di,ax                   ; byte in regen buffer
  2029.         xor     bh,bh
  2030.         sub     bx,32                   ; characters in font start at 32
  2031.         shl     bx,1
  2032.         shl     bx,1                    ; 8 bytes per char - hence * 8
  2033.         shl     bx,1
  2034.         mov     cx,8                    ; 8 bytes (scan lines) to transfer
  2035.         call    gcplot                  ; call character plot routine
  2036.         call    incx                    ; move to next char position
  2037.         pop     di
  2038.         pop     es
  2039.         pop     cx
  2040.         pop     bx
  2041.         pop     ax
  2042.         ret
  2043. gputc   endp
  2044.  
  2045. putctrl proc    near                    ; CONTROL CHARS = cursor movement
  2046.         push    ax                      ; save character
  2047.         cmp     al,FF                   ; formfeed?
  2048.         jne     putct0                  ; ne = no
  2049.         call    TEKCLS                  ; FF clears the screen
  2050.         jmp     putctx
  2051. putct0: cmp     al,BS                   ; BS? sends (logical) cursor back one
  2052.         jne     putct2                  ; ne = no, try next
  2053.         mov     ax,x_coord
  2054.         sub     ax,8                    ; so delete 8 dots (move left)
  2055.         jns     putct1                  ; ns = non-negative
  2056.         mov     ax,0                    ; but not less than 0
  2057. putct1: mov     x_coord,ax              ; and replace x coordinate
  2058.         mov     al,' '                  ; send a space
  2059.         call    putc
  2060.         sub     x_coord,8               ; restore cursor
  2061.         jmp     putctx
  2062. putct2: cmp     al,tab                  ; tabs move forward one char position
  2063.         jne     putct4                  ; ne = not a tab
  2064.         call    incx                    ; let incx move cursor right one col
  2065.         jmp     putctx
  2066. putct3: mov     x_coord,ax
  2067.         jmp     putctx
  2068. putct4: cmp     al,cr                   ; <CR> means go to beginning of line
  2069.         jne     putct5
  2070.         mov     x_coord,0               ; zero the x coordinate
  2071.         jmp     putctx
  2072. putct5: cmp     al,lf                   ; <LF> means go down 8 pixels (1 line)
  2073.         jne     putct7                  ; ne = not LF
  2074.         add     y_coord,8               ; border managed by outscrn and incx
  2075.         jmp     putctx
  2076. putct7: cmp     al,vt                   ; <VT> move up screen 1 line (8 pixels)
  2077.         jne     putctx
  2078.         sub     y_coord,8               ; subtract one line (8 pixels)
  2079.         jnc     putctx                  ; nc = space left
  2080.         mov     y_coord,8               ; else set to top of screen
  2081. putctx: pop     ax
  2082.         ret
  2083. putctrl endp
  2084.  
  2085. mputc   proc    near                    ; MONO put char in AL via Bios
  2086.         push    ax                      ; updates x_coord,y_coord with
  2087.         push    bx                      ; new cursor position
  2088.         push    cx
  2089.         push    dx
  2090.         mov     ah,0                    ; marker for cursor setting not needed
  2091.         cmp     al,' '                  ; control code?
  2092.         jae     mputc1                  ; ae = no, printable
  2093.         call    putctrl                 ; do cursor arithmetic
  2094.         mov     ah,1                    ; marker to set cursor but no display
  2095.  
  2096. mputc1: push    ax                      ; save char and marker
  2097.         mov     cl,3                    ; char cell is 8 x 8 dots
  2098.         mov     ax,x_coord              ; get resulting cursor PC positions
  2099.         shr     ax,cl
  2100.         mov     dl,al                   ; column
  2101.         mov     ax,y_coord
  2102.         sub     ax,8                    ; minus 8 dots, like other modes
  2103.         jnc     mputc2                  ; nc = non-negative
  2104.         mov     ax,0                    ; else start at the top
  2105.         mov     y_coord,8               ; here too
  2106. mputc2: shr     ax,cl
  2107.         mov     dh,al                   ; row
  2108.         mov     ah,2                    ; set cursor to x_coord,y_coord
  2109.         mov     bh,0                    ; page 0
  2110.         int     screen
  2111.         pop     ax
  2112.         cmp     ah,0                    ; write a char in al?
  2113.         jne     mputcx                  ; ne = no
  2114.         mov     ah,09h                  ; write char at cursor postion
  2115.         mov     cx,1                    ; just one char
  2116.         mov     bh,0                    ; page 0
  2117.         mov     bl,gfcol                ; foreground coloring
  2118.         int     screen
  2119.         inc     dl                      ; next column
  2120.         mov     ah,2                    ; set real cursor ahead of last char
  2121.         int     screen
  2122.         call    incx                    ; move logical cursor
  2123. mputcx: pop     dx
  2124.         pop     cx
  2125.         pop     bx
  2126.         pop     ax
  2127.         ret
  2128. mputc   endp
  2129.  
  2130. incx    proc    near                    ; move the logical cursor right
  2131.         mov     ax,x_coord              ; shift the (logical) cursor right
  2132.         add     ax,8                    ;  one character cell
  2133.         mov     x_coord,ax
  2134.         cmp     ax,xmax                 ; at end of the line?
  2135.         jbe     incx1                   ; b = no
  2136.         mov     x_coord,0               ; wrap to next line
  2137.         add     y_coord,8               ; next row
  2138.         mov     ax,ybot                 ; last scan line
  2139.         cmp     ax,y_coord              ; below bottom line?
  2140.         jge     incx1                   ; ge = no
  2141.         mov     y_coord,ax              ; set to bottom row
  2142.         mov     al,lf                   ; simulate a line feed operation
  2143.         call    outscrn                 ; invoke More message
  2144. incx1:  ret
  2145. incx    endp
  2146.  
  2147. ; EGA Character plot routine. Enter with bx pointing at font array for char
  2148. ; cx = number of bytes in char font, es:di = screen memory. Worker for gputc.
  2149. ; ccode: 0=plot in background colors, 1=foreground, 0ffh=xor with screen
  2150. gcega   proc    near
  2151. gcega1: mov     al,font[bx]             ; EGA byte plot: get bits from font
  2152.         push    bx
  2153. ;;;;;   mov     bh,0ffh                 ; write these bits to clear field
  2154. ;;;;;   mov     bl,0                    ; in background coloring
  2155. ;;;;;   call    ega_plt                 ; plot a byte
  2156.         mov     bh,al                   ; set bit pattern of character
  2157.         mov     bl,ccode                ; plot in back/fore/xor (ccode) colors
  2158.         call    ega_plt                 ; byte plot routine for EGA systems
  2159.         pop     bx
  2160.         inc     bx                      ; next byte of char pattern
  2161.         call    pincy                   ; next scan line (linelen is preset)
  2162.         loop    gcega1
  2163.         ret
  2164. gcega   endp
  2165.  
  2166. ; General Character plot routine. Enter with bx pointing at font array for
  2167. ; char, cx = number of bytes in char font, es:di = screen memory.
  2168. ; Worker for gputc.
  2169.  
  2170. gcgen   proc    near
  2171. gcgen1: mov     al,font[bx]             ; Non-EGA systems: get bits from font
  2172.         cmp     ccode,1                 ; write in foreground?
  2173.         je      gcgen2                  ; e = yes
  2174.         xor     es:[di],al              ; background or xor (same)
  2175.         jmp     short gcgen3
  2176. ;;;;    mov     es:[di],al              ; write desired pattern (no overwrite)
  2177. gcgen2: OR      es:[di],al              ; write desired pattern (no overwrite)
  2178. gcgen3: inc     bx                      ; point to next byte of char pattern
  2179.         call    pincy                   ; next scan line (linelen is preset)
  2180.         loop    gcgen1                  ; and repeat until complete
  2181.         ret
  2182. gcgen   endp
  2183.  
  2184. ; routines to manipulate ega graphics controller and mode register
  2185. ; command code in al, value in ah - destroys al and dx
  2186.  
  2187. ega_gc  proc    near                    ; ega graphics controller
  2188.         mov     dx,3ceh
  2189.         out     dx,al                   ; output command code
  2190.         inc     dx                      ; dx is now data port
  2191.         mov     al,ah                   ; get value to al
  2192.         out     dx,al                   ; output value
  2193.         ret
  2194. ega_gc  endp
  2195. ega_md  proc    near                    ; ega mode controller
  2196.         mov     dx,3c4h
  2197.         out     dx,al                   ; output command code
  2198.         inc     dx                      ; dx is now data port
  2199.         mov     al,ah                   ; get value to al
  2200.         out     dx,al                   ; output value
  2201.         ret
  2202. ega_md endp
  2203.  
  2204. ; Plot eight pixels using an EGA board
  2205. ; Enter with ES:[DI] pointing to screen address of byte,
  2206. ; bh has pattern of bits to be set, bl has attributes:
  2207. ;  0 = draw in background color, 1 = draw in foreground color,
  2208. ;  0ffh = XOR with current dot colors.
  2209. ; registers preserved
  2210.  
  2211. ega_plt proc    near
  2212.         push    ax
  2213.         push    dx
  2214.         mov     al,8                    ; command to set bit mask register
  2215.         mov     ah,bh                   ; get bits to be modified (1)
  2216.         call    ega_gc                  ; unprotect those bit positions
  2217.         mov     ah,gfcol                ; get foreground colour
  2218.         cmp     bl,1                    ; draw in foreground?
  2219.         je      ega2                    ; ne = no
  2220.         mov     ah,gbcol                ; get grahics background colour
  2221.         cmp     bl,0ffh                 ; do an XOR?
  2222.         jne     ega2                    ; ne = no
  2223.         mov     ah,0ffh                 ; XOR, touch all color bits
  2224. ega2:   mov     al,es:[di]              ; latch byte
  2225.         mov     es:[di],ah              ; set the byte
  2226.         pop     dx
  2227.         pop     ax
  2228.         ret
  2229. ega_plt endp
  2230.  
  2231. ; routine to set Hercules card to graphics mode - both pages are enabled
  2232.  
  2233. HGRAF   PROC    NEAR
  2234.         push    ax
  2235.         push    bx                      ; save used registers
  2236.         push    cx
  2237.         push    si
  2238.         mov     al,grph                 ; graph mode
  2239.         lea     si,gtable               ;  requires graphics table
  2240.         mov     bx,0
  2241.         mov     cx,4000h                ; clear 4000h words
  2242.         call    setmd                   ; and set the mode
  2243.         pop     si
  2244.         pop     cx
  2245.         pop     bx
  2246.         pop     ax
  2247.         ret
  2248. HGRAF   ENDP
  2249.  
  2250. ; set Hercules card to text mode
  2251.  
  2252. HTEXT   PROC    NEAR
  2253.         push    ax
  2254.         push    bx
  2255.         push    cx
  2256.         push    si
  2257.         mov     al,text                 ; text mode
  2258.         lea     si,ttable               ; requires text table
  2259.         mov     bx,0720h                ; blank value (space, white on black)
  2260.         mov     cx,2000                 ; whole screen to clear (80*25)
  2261.         call    setmd                   ; set the mode
  2262.         pop     si
  2263.         pop     cx
  2264.         pop     bx
  2265.         pop     ax
  2266.         ret
  2267. HTEXT   ENDP
  2268.  
  2269. ; Hercules mode set - called from HTEXT and HGRAF
  2270.  
  2271. SETMD   PROC    NEAR
  2272.         push    dx
  2273.         push    ax
  2274.         mov     dx,config               ; configuration port
  2275.         mov     al,genable              ; allow graphics mode to be set
  2276.         out     dx,al
  2277.         pop     ax
  2278.         push    ax
  2279.         push    cx                      ; save count
  2280.         mov     dx,cntrl                ; control port
  2281.         out     dx,al                   ; set to text or graphics
  2282.         mov     dx,index                ; send 12 bytes from table to 6845
  2283.         mov     cx,12                   ; number of registers to load
  2284.         xor     ah,ah                   ; start with register 0 of 6845
  2285.         cld
  2286. setmd1: jmp     $+2                     ; small pause for hardware
  2287.         mov     al,ah                   ; ah is counter
  2288.         out     dx,al                   ; set register
  2289.         inc     dx                      ; point to data port
  2290.         lodsb                           ; get next byte in table
  2291.         jmp     $+2                     ; small pause for hardware
  2292.         out     dx,al                   ; and send to 6845
  2293.         inc     ah                      ; next register
  2294.         dec     dx                      ; point to register port
  2295.         loop    setmd1                  ; and continue 'til cx=0
  2296.         pop     cx                      ; recover count
  2297.         cld
  2298.         push    di
  2299.         push    es
  2300.         mov     ax,segscn               ; start of screen
  2301.         mov     es,ax
  2302.         xor     di,di
  2303.         mov     ax,bx                   ; get blanking character
  2304.         rep     stosw                   ; store blanking char in whole screen
  2305.         pop     es
  2306.         pop     di
  2307.         mov     dx,cntrl                ; now to re-enable screen
  2308.         pop     ax                      ; get mode
  2309.         or      al,scrn_on              ; enable screen
  2310.         out     dx,al
  2311.         pop     dx
  2312.         ret
  2313. SETMD   ENDP
  2314.  
  2315. teksave proc    near            ; saves graphics screen from page 0 to page 1
  2316.         push    si
  2317.         push    di
  2318.         cmp     gpage,0         ; only graphics page 0 on display board?
  2319.         je      teksavx         ; e = yes, no saving possible here
  2320.         mov     si,segscn       ; segment (!) of current screen
  2321.         cmp     graph_mode,ega
  2322.         je      teksav1
  2323.         cmp     graph_mode,monoega
  2324.         je      teksav1
  2325.         cmp     graph_mode,colorega
  2326.         je      teksav1
  2327.         cmp     graph_mode,hercules
  2328.         je      teksav2
  2329.         jmp     short teksavx   ; else nothing
  2330. teksav1:mov     di,segega+800h  ; EGA page 1 screen segment
  2331.         call    egasr           ; call common save/restore code
  2332.         jmp     short teksavx
  2333. teksav2:mov     di,seghga+800h  ; Hercules page 1 screen segment
  2334.         call    hgasr           ; call common save/restore code
  2335. teksavx:pop     di
  2336.         pop     si
  2337.         ret
  2338. teksave endp
  2339.  
  2340. tekrest proc    near            ; saves graphics screen of page 0 in page 1
  2341.         push    si
  2342.         push    di
  2343.         cmp     gpage,0         ; only graphics page 0 on display board?
  2344.         jne     tekres0         ; ne = no, more so work to do here
  2345.         call    tekcls1         ;  else clear the screen to color it
  2346.         jmp     short tekresx   ;  and exit
  2347. tekres0:mov     di,segscn       ; segment (!) of new graphics screen
  2348.         cmp     graph_mode,ega
  2349.         je      tekres1
  2350.         cmp     graph_mode,monoega
  2351.         je      tekres1
  2352.         cmp     graph_mode,colorega
  2353.         je      tekres1
  2354.         cmp     graph_mode,hercules
  2355.         je      tekres2
  2356.         jmp     short tekresx   ; else nothing
  2357. tekres1:mov     si,segega+800h  ; segment of EGA page 1
  2358.         call    egasr           ; call common save/restore code
  2359.         jmp     short tekresx
  2360. tekres2:mov     si,seghga+800h  ; segment of Hercules page 1
  2361.         call    hgasr           ; call common save/restore code
  2362. tekresx:pop     di
  2363.         pop     si
  2364.         ret
  2365. tekrest endp
  2366.  
  2367. egasr   proc    near            ; common code for Tek ega save/restore ops
  2368.         push    ax
  2369.         push    cx
  2370.         push    dx
  2371.         mov     ax,0f00h        ; enable 4 plane set/resets
  2372.         call    ega_gc          ; set controller
  2373.         mov     ax,0f01h        ; enable Set/Reset register
  2374.         call    ega_gc
  2375.         mov     ax,0f02h        ; set color compare register for 4 planes
  2376.         call    ega_gc
  2377.         mov     ax,0905h        ; set mode reg: write latches, read mode
  2378.         call    ega_gc
  2379.         mov     ax,0ff02h       ; enable all planes
  2380.         call    ega_md
  2381.         mov     cx,ybot         ; last scan line
  2382.         inc     cx              ; number of scan lines
  2383.         mov     ax,80           ; bytes per scan line
  2384.         mul     cx
  2385.         mov     cx,ax
  2386.         push    es              ; save es
  2387.         push    ds              ; save ds
  2388.         mov     es,di           ; destination, set es to video memory
  2389.         mov     ds,si           ; source, set ds to video memory
  2390.         xor     si,si           ; clear offset fields
  2391.         xor     di,di
  2392.         cld
  2393.         rep     movsb           ; copy from page [si] to page [di]
  2394.         pop     ds              ; recover ds
  2395.         pop     es              ; and other registers
  2396.         mov     ax,0000h        ; disable 4 plane set/resets
  2397.         call    ega_gc          ; set controller
  2398.         mov     ax,0001h        ; disable Set/Reset register
  2399.         call    ega_gc          ; set controller
  2400.         mov     ax,0002h        ; disable color compare register
  2401.         call    ega_gc
  2402.         mov     ax,1005h        ; set mode reg: write latches, odd/even
  2403.         call    ega_gc
  2404.         pop     dx
  2405.         pop     cx
  2406.         pop     ax
  2407.         ret
  2408. egasr   endp
  2409.  
  2410. hgasr   proc    near            ; Hercules save restore screen
  2411.         push    cx
  2412.         mov     cx,4000h        ; number of words to move
  2413.         push    es              ; save es
  2414.         push    ds              ; save ds
  2415.         mov     es,di           ; destination, set es to video memory
  2416.         mov     ds,si           ; source, set ds to video memory
  2417.         xor     si,si           ; clear offset fields
  2418.         xor     di,di
  2419.         cld
  2420.         rep     movsw           ; copy from page [si] to page [di]
  2421.         pop     ds              ; recover ds
  2422.         pop     es              ; and other registers
  2423.         pop     cx
  2424.         ret
  2425. hgasr   endp
  2426. code    ends
  2427.         end
  2428.  
  2429.  
  2430.